home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / unix / rcs.06 < prev    next >
Internet Message Format  |  1989-11-19  |  96KB

  1. Path: xanth!ames!apple!sun-barr!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i221:  rcs - revision control system, Part06/14
  5. Message-ID: <128097@sun.Eng.Sun.COM>
  6. Date: 19 Nov 89 09:24:52 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 4084
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: rsbx@cbmvax.commodore.com (Raymond S. Brand)
  12. Posting-number: Volume 89, Issue 221
  13. Archive-name: unix/rcs.06
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    doc/rcs.1l
  24. #    doc/rcsclean.1l
  25. #    doc/rcsdiff.1l
  26. #    doc/rcsfile.5l
  27. #    doc/rcsfreeze.1l
  28. #    doc/rcsintro.1l
  29. #    doc/rcsmerge.1l
  30. #    doc/rlog.1l
  31. #    ked/ked.c,v
  32. #    rcs/readme
  33. #    rcs/rcs.rcsfiles/maketime.c,v
  34. # This is archive 6 of a 14-part kit.
  35. # This archive created: Sun Nov 19 01:12:07 1989
  36. if `test ! -d doc`
  37. then
  38.   mkdir doc
  39.   echo "mkdir doc"
  40. fi
  41. echo "extracting doc/rcs.1l"
  42. sed 's/^X//' << \SHAR_EOF > doc/rcs.1l
  43. X.TH RCS 1L "" "Purdue University"
  44. X.SH NAME
  45. Xrcs \- change RCS file attributes
  46. X.SH SYNOPSIS
  47. X.B rcs
  48. X[ options ]
  49. Xfile ... 
  50. X.SH DESCRIPTION
  51. X.I Rcs
  52. Xcreates new RCS files or changes attributes of existing ones.
  53. XAn RCS file contains multiple revisions of text,
  54. Xan access list, a change log, 
  55. Xdescriptive text,
  56. Xand some control attributes.
  57. XFor \fIrcs\fR to work, the caller's login name must be on the access list,
  58. Xexcept if the access list is empty, the caller is the owner of the file
  59. Xor the superuser, or
  60. Xthe \fB\-i\fR option is present. 
  61. X.PP
  62. XFiles ending in `,v' are RCS files, all others are working files. If
  63. Xa working file is given, \fIrcs\fR tries to find the corresponding
  64. XRCS file first in directory ./RCS and then in the current directory,
  65. Xas explained in
  66. X.IR co (1L).
  67. X.TP 11
  68. X.B \-i
  69. Xcreates and initializes a new RCS file, but does not deposit any revision.
  70. XIf the RCS file has no path prefix, \fIrcs\fR tries to place it
  71. Xfirst into the subdirectory ./RCS, and then into the current directory.
  72. XIf the RCS file
  73. Xalready exists, an error message is printed.
  74. X.TP
  75. X.BI \-a "logins"
  76. Xappends the login names appearing in the comma-separated list \fIlogins\fR
  77. Xto the access list of the RCS file.
  78. X.TP
  79. X.BI \-A "oldfile"
  80. Xappends the access list of \fIoldfile\fR to the access list of the RCS file. 
  81. X.TP
  82. X.BR \-e [\fIlogins\fR]
  83. Xerases the login names appearing in the comma-separated list \fIlogins\fR
  84. Xfrom the access list of the RCS file.
  85. XIf \fIlogins\fR is omitted, the entire access list is erased.
  86. X.TP
  87. X.BR \-b [\fIrev\fR]
  88. Xsets the default branch to \fIrev\fR. If \fIrev\fR is omitted, the default
  89. Xbranch is reset to the (dynamically) highest branch on the trunk.
  90. X.TP
  91. X.BI \-c "string"
  92. Xsets the comment leader to \fIstring\fR. The comment leader
  93. Xis printed before every log message line generated by the keyword 
  94. X$\&Log$  during checkout (see
  95. X.IR co (1L)).
  96. XThis is useful for programming 
  97. Xlanguages without multi-line comments. During \fBrcs -i\fR or initial 
  98. X\fBci\fR, the comment leader is guessed from the suffix of the working file. 
  99. X.TP
  100. X.BR \-l [\fIrev\fR]
  101. Xlocks the revision with number \fIrev\fR.
  102. XIf a branch is given, the latest revision on that branch is locked.
  103. XIf \fIrev\fR is omitted, the latest revision on the default branch is locked.
  104. XLocking prevents overlapping changes.
  105. XA lock is removed with \fBci\fR or \fBrcs -u\fR (see below).
  106. X.TP
  107. X.BR \-u [\fIrev\fR]
  108. Xunlocks the revision with number \fIrev\fR.
  109. XIf a branch is given, the latest revision on that branch is unlocked.
  110. XIf \fIrev\fR is omitted, the latest lock held by the caller is removed.
  111. XNormally, only the locker of a revision may unlock it.
  112. XSomebody else unlocking a revision breaks the lock. 
  113. XThis causes a mail message to be sent to the original locker.
  114. XThe message contains a commentary solicited from the breaker.
  115. XThe commentary is terminated with a line containing a single `.' or
  116. Xcontrol-D.
  117. X.TP
  118. X.B \-L
  119. Xsets locking to \fIstrict\fR. Strict locking means that the owner
  120. Xof an RCS file is not exempt from locking for checkin.
  121. XThis option should be used for files that are shared.
  122. X.TP
  123. X.B \-U
  124. Xsets locking to non-strict. Non-strict locking means that the owner of
  125. Xa file need not lock a revision for checkin. 
  126. XThis option should NOT be used for files that are shared.
  127. XThe default (\fB\-L\fR or \fB\-U\fR) is determined by your system administrator.
  128. X.TP
  129. X.B \-n\fIname\fR[:\fIrev\fR]
  130. Xassociates the symbolic name \fIname\fR with the branch or
  131. Xrevision \fIrev\fR. 
  132. X\fIRcs\fR prints an error message if \fIname\fR is already associated with
  133. Xanother number.
  134. XIf \fIrev\fR is omitted, the symbolic name is deleted.
  135. X.TP
  136. X.B \-N\fIname\fR[:\fIrev\fR]
  137. Xsame as \fB\-n\fR, except that it overrides a previous assignment of 
  138. X\fIname\fR.
  139. X.TP
  140. X.BI \-o "range"
  141. Xdeletes ("outdates") the revisions given by \fIrange\fR.
  142. XA range consisting of a single revision number means that revision.
  143. XA range consisting of a branch number means the latest revision on that
  144. Xbranch.
  145. XA range of the form \fIrev1-rev2\fR means 
  146. Xrevisions \fIrev1\fR to \fIrev2\fR on the same branch, 
  147. X\fI-rev\fR means from the beginning of the branch containing
  148. X\fIrev\fR up to and including \fIrev\fR, and \fIrev-\fR means
  149. Xfrom revision \fIrev\fR to the end of the branch containing \fIrev\fR.
  150. XNone of the outdated revisions may have branches or locks.
  151. X.TP
  152. X.B \-q
  153. Xquiet mode; diagnostics are not printed.
  154. X.TP
  155. X.B \-s\fIstate\fR[:\fIrev\fR]
  156. Xsets the state attribute of the revision \fIrev\fR to \fIstate\fR. 
  157. XIf \fIrev\fR is a branch number, the latest revision on that branch is
  158. Xassumed.
  159. XIf \fIrev\fR is omitted, the latest revision on the default branch is assumed.
  160. XAny identifier is acceptable for \fIstate\fR.
  161. XA useful set of states
  162. Xis \fIExp\fR (for experimental), \fIStab\fR (for stable), and \fIRel\fR (for
  163. Xreleased).
  164. XBy default,
  165. X.IR ci (1L)
  166. Xsets the state of a revision to \fIExp\fR.
  167. X.TP
  168. X.BR \-t [\fItxtfile\fR]
  169. Xwrites descriptive text into the RCS file (deletes the existing text).
  170. XIf \fItxtfile\fR is omitted, 
  171. X\fIrcs\fR prompts the user for text supplied from the standard input,
  172. Xterminated with a line containing a single `.' or control-D.
  173. XOtherwise, the descriptive text is copied from the file \fItxtfile\fR.
  174. XIf the \fB\-i\fR option is present, descriptive text is requested
  175. Xeven if \fB\-t\fR is not given.
  176. XThe prompt is suppressed if the standard input is not a terminal.
  177. X.SH DIAGNOSTICS
  178. XThe RCS file name and the revisions outdated are written to
  179. Xthe diagnostic output.
  180. XThe exit status always refers to the last RCS file operated upon,
  181. Xand is 0 if the operation was successful, 1 otherwise.
  182. X.SH FILES
  183. XThe caller of the command
  184. Xmust have read/write permission for the directory containing
  185. Xthe RCS file and read permission for the RCS file itself.
  186. X.I Rcs
  187. Xcreates a semaphore file in the same directory as the RCS
  188. Xfile to prevent simultaneous update.
  189. XFor changes, \fIrcs\fR always creates a new file. On successful completion,
  190. X\fIrcs\fR deletes the old one and renames the new one.
  191. XThis strategy makes links to RCS files useless.
  192. X.SH IDENTIFICATION
  193. X.de VL
  194. X\\$2
  195. X..
  196. XAuthor: Walter F. Tichy,
  197. XPurdue University, West Lafayette, IN, 47907.
  198. X.sp 0
  199. XRevision Number:
  200. X.VL $Revision: 1.3 $
  201. X; Release Date:
  202. X.VL $Date: 89/05/02 11:14:37 $
  203. X\&.
  204. X.sp 0
  205. XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
  206. X.SH SEE ALSO
  207. Xco(1L), ci(1L), ident(1L), rcsdiff(1L), rcsintro(1L), rcsmerge(1L), rlog(1L),
  208. Xrcsfile(5L)
  209. X.sp 0
  210. XWalter F. Tichy, "Design, Implementation, and Evaluation of a Revision Control
  211. XSystem," in \fIProceedings of the 6th International Conference on Software
  212. XEngineering\fR, IEEE, Tokyo, Sept. 1982.
  213. SHAR_EOF
  214. echo "extracting doc/rcsclean.1l"
  215. sed 's/^X//' << \SHAR_EOF > doc/rcsclean.1l
  216. X.TH RCSCLEAN 1L "" "Purdue University"
  217. X.SH NAME
  218. Xrcsclean \- clean up working files
  219. X.SH SYNOPSIS
  220. X\fBrcsclean\fR [ \fB-r\fIrev\fR ] [ \fB-q\fIrev\fR ] file...
  221. X.SH DESCRIPTION
  222. X.I Rcsclean
  223. Xremoves working files that were checked out and never modified.
  224. XFor each file given, \fIrcsclean\fR
  225. Xcompares the working file and a revision in the corresponding
  226. XRCS file. If it finds no difference, it removes the working file, and,
  227. Xif the revision was locked by the caller, unlocks the revision.
  228. X.PP
  229. XA file name ending in ',v' is an RCS file name, otherwise a
  230. Xworking file name. \fIRcsclean\fR derives the working file name from the RCS
  231. Xfile name and vice versa, as explained in
  232. X.IR co (1L).
  233. XPairs consisting
  234. Xof both an RCS and a working file name may also be specified.
  235. X.PP
  236. X\fIRev\fR specifies with which revision the working file is compared.
  237. XIf \fIrev\fR is omitted, \fIrcsclean\fR compares the working file with
  238. Xthe latest revision
  239. Xon the default branch (normally the highest branch on the trunk).
  240. XThe option \fB-q\fR suppresses diagnostics.
  241. X.PP
  242. X\fIRcsclean\fR is useful for "clean" targets in Makefiles.
  243. XNote that
  244. X.IR rcsdiff (1L)
  245. Xprints out the differences.
  246. XAlso,
  247. X.IR ci (1L)
  248. Xnormally asks whether to check in a file
  249. Xif it was not changed.
  250. X.SH EXAMPLES
  251. X.nf
  252. XThe command
  253. X
  254. X    rcsclean *.c *.h
  255. X
  256. X.fi
  257. Xremoves all working files ending in ".c" or ".h" that were not changed
  258. Xsince their checkout.
  259. X.SH DIAGNOSTICS
  260. XThe exit status is 0 if there were no differences
  261. Xduring the last comparison or if the last working file did not exist,
  262. X1 if there were differences, and 2 if there were errors.
  263. X.SH IDENTIFICATION
  264. X.de VL
  265. X\\$2
  266. X..
  267. XAuthor: Walter F. Tichy,
  268. XPurdue University, West Lafayette, IN, 47907.
  269. X.sp 0
  270. XRevision Number:
  271. X.VL $Revision: 1.2 $
  272. X; Release Date:
  273. X.VL $Date: 89/05/02 11:15:26 $
  274. X\&.
  275. X.sp 0
  276. XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
  277. X.SH SEE ALSO
  278. Xco(1L), ci(1L), ident(1L), rcs(1L), rcsdiff(1L), rcsintro(1L), rcsmerge(1L),
  279. Xrlog(1L), rcsfile(5L).
  280. SHAR_EOF
  281. echo "extracting doc/rcsdiff.1l"
  282. sed 's/^X//' << \SHAR_EOF > doc/rcsdiff.1l
  283. X.TH RCSDIFF 1L "" "Purdue University"
  284. X.SH NAME
  285. Xrcsdiff \- compare RCS revisions
  286. X.SH SYNOPSIS
  287. X\fBrcsdiff\fR [ \fB\-biwt\fR ] [ \fB\-cefhn\fR ] [ \fB\-q\fR ] [ \fB\-r\fIrev1\fR ] [ \fB\-r\fIrev2\fR ] file ...
  288. X.SH DESCRIPTION
  289. X.I Rcsdiff
  290. Xruns
  291. X.IR diff (1)
  292. Xto compare two revisions of each RCS file given.
  293. XA file name ending in ',v' is an RCS file name, otherwise a
  294. Xworking file name. \fIRcsdiff\fR derives the working file name from the RCS
  295. Xfile name and vice versa, as explained in
  296. X.IR co (1L).
  297. XPairs consisting
  298. Xof both an RCS and a working file name may also be specified.
  299. X.PP
  300. XThe options \fB\-b\fR, \fB\-i\fR, \fB\-w\fR, \fB\-t\fR,
  301. X\fB\-c\fR, \fB\-e\fR, \fB\-f\fR, and \fB\-h\fR,
  302. Xhave the same effect as described in
  303. X.IR diff (1);
  304. Xoption
  305. X\fB\-n\fR generates an edit script of the format used by RCS.
  306. XThe option \fB\-q\fR suppresses diagnostic output.
  307. X.PP
  308. XIf both \fIrev1\fR and \fIrev2\fR
  309. Xare omitted, \fIrcsdiff\fR compares the latest revision on the
  310. Xdefault branch (normally the highest branch on the trunk)
  311. Xwith the contents of the corresponding working file. This is useful
  312. Xfor determining what you changed since the last checkin.
  313. X.PP
  314. XIf \fIrev1\fR is given, but \fIrev2\fR is omitted,
  315. X\fIrcsdiff\fR compares revision \fIrev1\fR of the RCS file with
  316. Xthe contents of the corresponding working file.
  317. X.PP
  318. XIf both \fIrev1\fR and \fIrev2\fR are given,
  319. X\fIrcsdiff\fR compares revisions \fIrev1\fR and \fIrev2\fR of the RCS file.
  320. X.PP
  321. XBoth \fIrev1\fR and \fIrev2\fR may be given numerically or symbolically,
  322. Xand may actually be attached to any of the options.
  323. X.SH EXAMPLES
  324. X.nf
  325. XThe command
  326. X
  327. X.B "        rcsdiff  f.c
  328. X
  329. X.fi
  330. Xruns \fIdiff\fR on the latest revision on the default branch of RCS file f.c,v
  331. Xand the contents of working file f.c.
  332. X.SH DIAGNOSTICS
  333. XThe exit status is 0 if there were no differences during the last comparison,
  334. X1 if there were differences, and 2 if there were errors.
  335. X.SH IDENTIFICATION
  336. X.de VL
  337. X\\$2
  338. X..
  339. XAuthor: Walter F. Tichy,
  340. XPurdue University, West Lafayette, IN, 47907.
  341. X.sp 0
  342. XRevision Number:
  343. X.VL $Revision: 1.3 $
  344. X; Release Date:
  345. X.VL $Date: 89/05/02 11:16:01 $
  346. X\&.
  347. X.sp 0
  348. XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
  349. X.SH SEE ALSO
  350. Xci(1L), co(1L), diff(1), ident(1L), rcs(1L), rcsintro(1L), rcsmerge(1L), rlog(1L)
  351. X.br
  352. XWalter F. Tichy, "Design, Implementation, and Evaluation of a Revision Control
  353. XSystem," in \fIProceedings of the 6th International Conference on Software
  354. XEngineering\fR, IEEE, Tokyo, Sept. 1982.
  355. SHAR_EOF
  356. echo "extracting doc/rcsfile.5l"
  357. sed 's/^X//' << \SHAR_EOF > doc/rcsfile.5l
  358. X.TH RCSFILE 5L "" "Purdue University"
  359. X.SH NAME
  360. Xrcsfile \- format of RCS file
  361. X.SH DESCRIPTION
  362. XAn RCS file is an ASCII file. Its contents are described by the grammar
  363. Xbelow. The text is free format, i.e., spaces, tabs and new lines have
  364. Xno significance except in strings. Strings are enclosed by `@'.
  365. XIf a string contains a `@', it must be doubled.
  366. X.PP
  367. XThe meta syntax uses the following conventions: `|' (bar) separates
  368. Xalternatives; `{' and `}' enclose optional phrases; `{' and `}*' enclose
  369. Xphrases that may be repeated zero or more times;
  370. X`{' and '}+' enclose phrases that must appear at least once and may be
  371. Xrepeated;
  372. X`<' and `>' enclose nonterminals.
  373. X.PP
  374. X.ta 1.5i 2.0i 3i
  375. X.fc ~
  376. X.nf
  377. X
  378. X<rcstext>  ~~::=~~<admin> {<delta>}* <desc> {<deltatext>}*
  379. X           
  380. X<admin>    ~~::=~~\fBhead\fR     ~~{<num>};
  381. X           ~~   ~~\fBbranch\fR   ~~{<num>};
  382. X           ~~   ~~\fBaccess\fR   ~~{<id>}*;
  383. X           ~~   ~~\fBsymbols\fR  ~~{<id> : <num>}*;  
  384. X           ~~   ~~\fBlocks\fR    ~~{<id> : <num>}*;
  385. X           ~~   ~~\fBcomment\fR  ~~{<string>};
  386. X           
  387. X<delta>    ~~::=~~<num>
  388. X           ~~   ~~\fBdate\fR     ~~<num>;
  389. X           ~~   ~~\fBauthor\fR   ~~<id>;
  390. X           ~~   ~~\fBstate\fR    ~~{<id>};
  391. X           ~~   ~~\fBbranches\fR ~~{<num>}*;
  392. X           ~~   ~~\fBnext\fR     ~~{<num>};
  393. X           
  394. X<desc>     ~~::=~~\fBdesc\fR     ~~<string>
  395. X
  396. X<deltatext>~~::=~~<num>   
  397. X           ~~   ~~\fBlog\fR      ~~<string>
  398. X           ~~   ~~\fBtext\fR     ~~<string>
  399. X
  400. X
  401. X<num>      ~~::=~~{<digit>{.}}+
  402. X             
  403. X<digit>    ~~::=~~0 | 1 | ... | 9
  404. X             
  405. X<id>       ~~::=~~<letter>{<idchar>}*
  406. X
  407. X<letter>   ~~::=~~A | B | ... | Z | a | b | ... | z
  408. X
  409. X<idchar>   ~~::=~~Any printing ASCII character except space,
  410. X           ~~   ~~tab, carriage return, new line, and <special>.
  411. X
  412. X<special>  ~~::=~~; | : | , | @
  413. X
  414. X<string>   ~~::=~~@{any ASCII character, with `@' doubled}*@
  415. X
  416. X.fi
  417. X.PP
  418. XIdentifiers are case sensitive. Keywords are in lower case only.
  419. XThe sets of keywords and identifiers may overlap.
  420. X.PP
  421. XThe <delta> nodes form a tree. All nodes whose numbers
  422. Xconsist of a single pair
  423. X(e.g., 2.3, 2.1, 1.3, etc.)
  424. Xare on the "trunk", and are linked through the \fBnext\fR
  425. Xfield in order of decreasing numbers. The \fBhead\fR field in the
  426. X<admin> node points to the head of that sequence (i.e., contains
  427. Xthe highest pair). 
  428. XThe \fBbranch\fR node in the admin node indicates the default
  429. Xbranch (or revision) for most RCS operations. If empty, the default
  430. Xbranch is the highest branch on the trunk.
  431. X.PP
  432. XAll <delta> nodes whose numbers consist of 2n fields (n\(>=2)
  433. X(e.g., 3.1.1.1, 2.1.2.2, etc.)
  434. Xare linked as follows. All nodes whose first (2n)-1 number fields are identical
  435. Xare linked through the \fBnext\fR field in order of increasing numbers.
  436. XFor each such sequence, 
  437. Xthe <delta> node whose number is identical to the first 
  438. X2(n-1) number fields of the deltas on that sequence is called the branchpoint.
  439. XThe \fBbranches\fR field of a node contains a list of the
  440. Xnumbers of the first nodes of all sequences for which it is a branchpoint.
  441. XThis list is ordered in increasing numbers.
  442. X.sp 1
  443. X.ne 38
  444. XExample:
  445. X.eo
  446. X.nf
  447. X.vs 12pts
  448. X.cs 1 20
  449. X.if t .in +0.5i
  450. X                           Head
  451. X                             |
  452. X                             |
  453. X                             v
  454. X                         ---------
  455. X   / \          / \      |       |      / \           / \     
  456. X  /   \        /   \     |  2.1  |     /   \         /   \
  457. X /     \      /     \    |       |    /     \      /       \
  458. X/1.2.1.3\    /1.3.1.1\   |       |   /1.2.2.2\   /1.2.2.1.1.1\
  459. X---------    ---------   ---------   ---------   -------------
  460. X    ^            ^           |           ^             ^
  461. X    |            |           |           |             |
  462. X    |            |           v           |             |
  463. X   / \           |       ---------      / \            |
  464. X  /   \          |       \  1.3  /     /   \           |
  465. X /     \         ---------\     /     /     \-----------
  466. X/1.2.1.1\                  \   /     /1.2.2.1\           
  467. X---------                   \ /      --------- 
  468. X    ^                        |           ^     
  469. X    |                        |           |     
  470. X    |                        v           |     
  471. X    |                    ---------       |     
  472. X    |                    \  1.2  /       |     
  473. X    ----------------------\     /---------     
  474. X                           \   /               
  475. X                            \ /                
  476. X                             |                 
  477. X                             |                 
  478. X                             v                 
  479. X                         ---------             
  480. X                         \  1.1  /             
  481. X                          \     /              
  482. X                           \   /               
  483. X                            \ /                
  484. X                                               
  485. X
  486. X.if t .in -0.5i
  487. X.cs 1
  488. X.ec
  489. X.ce
  490. XFig. 1: A revision tree
  491. X.fi
  492. X.PP
  493. X.SH IDENTIFICATION
  494. X.de VL
  495. X\\$2
  496. X..
  497. XAuthor: Walter F. Tichy,
  498. XPurdue University, West Lafayette, IN, 47907.
  499. X.sp 0
  500. XRevision Number:
  501. X.VL $Revision: 1.2 $
  502. X; Release Date:
  503. X.VL $Date: 89/05/02 11:16:56 $
  504. X\&.
  505. X.sp 0
  506. XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
  507. X.SH SEE ALSO
  508. Xci(1L), co(1L), ident(1L), rcs(1L), rcsdiff(1L), rcsmerge(1L), rlog(1L),
  509. X.br
  510. XWalter F. Tichy, "Design, Implementation, and Evaluation of a Revision Control
  511. XSystem," in \fIProceedings of the 6th International Conference on Software
  512. XEngineering\fR, IEEE, Tokyo, Sept. 1982.
  513. SHAR_EOF
  514. echo "extracting doc/rcsfreeze.1l"
  515. sed 's/^X//' << \SHAR_EOF > doc/rcsfreeze.1l
  516. X.TH RCSFREEZE 1L "" "Purdue University"
  517. X.SH NAME
  518. Xrcsfreeze \- freeze a configuration of sources checked in under RCS
  519. X.SH SYNOPSIS
  520. X.B rcsfreeze
  521. X[symbolic revision name]
  522. X.SH DESCRIPTION
  523. XThe
  524. X.I rcsfreeze
  525. Xcommand has the purpose of assigning a symbolic revision
  526. Xnumber to a set of RCS files, which form a valid configuration.
  527. X.PP
  528. XThe idea is to run
  529. X.I rcsfreeze
  530. Xeach time a new version is checked
  531. Xin. A unique symbolic revision number (\c
  532. X.BI C_ number,
  533. Xwhere
  534. X.I number
  535. Xis increased each time rcsfreeze is run) is then assigned to the most
  536. Xrecent revision of each RCS file of the main trunk.
  537. X.PP
  538. XIf the command is invoked with an argument, then this
  539. Xargument is used as the symbolic name to freeze a configuration.
  540. XThe unique identifier is still generated
  541. Xand is listed in the log file but it will not appear as
  542. Xpart of the symbolic revision name in the actual RCS files.
  543. X.PP
  544. XA log message is requested from the user which is saved for future
  545. Xreferences.
  546. X.PP
  547. XThe shell script works only on all RCS files at one time.
  548. XIt is important that all changed files are checked in (there are
  549. Xno precautions against any error in this respect). Run
  550. X.IR rcsclean (1L)
  551. Xfirst and see whether any sources remain in the current directory.
  552. X.SH FILES
  553. X.TP 2.5i
  554. X[RCS/]rcsfreeze.version
  555. Xfor the version number
  556. X.TP
  557. X[RCS/]rscfreeze.log
  558. Xfor the log messages, most recent log message first.
  559. X.SH AUTHOR
  560. XStephan v. Bechtolsheim
  561. X.SH "SEE ALSO"
  562. Xrcs(1L), rlog(1L), rcsclean(1L)
  563. X.SH BUGS
  564. XThe program does not check whether there are any sources checked out
  565. Xand modified.
  566. SHAR_EOF
  567. echo "extracting doc/rcsintro.1l"
  568. sed 's/^X//' << \SHAR_EOF > doc/rcsintro.1l
  569. X.TH RCSINTRO 1L "May 11, 1983" "Purdue University"
  570. X.SH NAME
  571. Xrcsintro - introduction to RCS commands
  572. X.SH DESCRIPTION
  573. XThe Revision Control System (RCS) manages multiple revisions of text files.
  574. XRCS automates the storing, retrieval, logging, identification, and merging
  575. Xof revisions. RCS is useful for text that is revised frequently, for example
  576. Xprograms, documentation, graphics, papers, form letters, etc.
  577. X.PP
  578. XThe basic user interface is extremely simple. The novice only needs
  579. Xto learn two commands:
  580. X.IR ci (1L)
  581. Xand
  582. X.IR co (1L).
  583. X\fICi\fR, short for "check in", deposits the contents of a
  584. Xtext file into an archival file called an RCS file. An RCS file
  585. Xcontains all revisions of a particular text file.
  586. X\fICo\fR, short for "check out", retrieves revisions from an RCS file.
  587. X.PP
  588. X.B "Functions of RCS"
  589. X.PP
  590. X.IP \(bu
  591. XStorage and retrieval of multiple revisions of text. RCS saves all old
  592. Xrevisions in a space efficient way.
  593. XChanges no longer destroy the original, because the
  594. Xprevious revisions remain accessible. Revisions can be retrieved according to
  595. Xranges of revision numbers, symbolic names, dates, authors, and
  596. Xstates.
  597. X.IP \(bu
  598. XMaintenance of a complete history of changes. RCS logs all changes automatically.
  599. XBesides the text of each revision, RCS stores the author, the date and time of
  600. Xcheck-in, and a log message summarizing the change.
  601. XThe logging makes it easy to find out
  602. Xwhat happened to a module, without having to compare
  603. Xsource listings or having to track down colleagues.
  604. X.IP \(bu
  605. XResolution of access conflicts. When two or more programmers wish to
  606. Xmodify the same revision, RCS alerts the programmers and prevents one
  607. Xmodification from corrupting the other.
  608. X.IP \(bu
  609. XMaintenance of a tree of Revisions. RCS can maintain separate lines of development
  610. Xfor each module. It stores a tree structure that represents the
  611. Xancestral relationships among revisions.
  612. X.IP \(bu
  613. XMerging of revisions and resolution of conflicts.
  614. XTwo separate lines of development of a module can be coalesced by merging.
  615. XIf the revisions to be merged affect the same sections of code, RCS alerts the
  616. Xuser about the overlapping changes.
  617. X.IP \(bu
  618. XRelease and configuration control. Revisions can be assigned symbolic names
  619. Xand marked as released, stable, experimental, etc.
  620. XWith these facilities, configurations of modules can be
  621. Xdescribed simply and directly.
  622. X.IP \(bu
  623. XAutomatic identification of each revision with name, revision number,
  624. Xcreation time, author, etc.
  625. XThe identification is like a stamp that can be embedded at an appropriate place
  626. Xin the text of a revision.
  627. XThe identification makes it simple to determine which
  628. Xrevisions of which modules make up a given configuration.
  629. X.IP \(bu
  630. XMinimization of secondary storage. RCS needs little extra space for
  631. Xthe revisions (only the differences). If intermediate revisions are
  632. Xdeleted, the corresponding deltas are compressed accordingly.
  633. X.sp
  634. X.PP
  635. X.B "Getting Started with RCS"
  636. X.PP
  637. XSuppose you have a file f.c that you wish to put under control of RCS. 
  638. XInvoke the check-in command
  639. X.PP
  640. X.ti 1.5i
  641. X.B "ci  f.c 
  642. X.PP
  643. XThis command creates the RCS file f.c,v, stores f.c into it as revision 1.1, and
  644. Xdeletes f.c.  It also asks you for a description. The description
  645. Xshould be a synopsis of the contents of the file. All later check-in
  646. Xcommands will ask you for a log entry, which should summarize the
  647. Xchanges that you made.
  648. X.PP
  649. XFiles ending in ,v are called RCS files (`v' stands for `versions'),
  650. Xthe others are called working files.
  651. XTo get back the working file f.c in the previous example, use the check-out
  652. Xcommand
  653. X.PP
  654. X.ti 1.5i
  655. X.B "co  f.c
  656. X.PP
  657. XThis command extracts the latest revision from f.c,v and writes
  658. Xit into f.c. You can now edit f.c and check it back in by invoking
  659. X.PP
  660. X.ti 1.5i
  661. X.B "ci  f.c
  662. X.PP
  663. X\fICi\fR increments the revision number properly. 
  664. XIf \fIci\fR complains with the message
  665. X.PP
  666. X        ci error: no lock set by <your login>
  667. X.PP
  668. Xthen your system administrator has decided to create all RCS files
  669. Xwith the locking attribute set to `strict'. In this case, you should
  670. Xhave locked the revision during the previous check-out. Your last check-out
  671. Xshould have been
  672. X.PP
  673. X.ti 1.5i
  674. X.B "co  \-l  f.c
  675. X.PP
  676. XOf course, it is too late now to do the check-out with locking, because you
  677. Xprobably modified f.c already, and a second check-out would
  678. Xoverwrite your modifications. Instead, invoke
  679. X.PP
  680. X.ti 1.5i
  681. X.B "rcs  \-l  f.c
  682. X.PP
  683. XThis command will lock the latest revision for you, unless somebody
  684. Xelse got ahead of you already. In this case, you'll have to negotiate with 
  685. Xthat person.
  686. X.PP
  687. XLocking assures that you, and only you, can check in the next update, and
  688. Xavoids nasty problems if several people work on the same file.
  689. XEven if a revision is locked, it can still be checked out for
  690. Xreading, compiling, etc. All that locking
  691. Xprevents is a CHECK-IN by anybody but the locker.
  692. X.PP
  693. XIf your RCS file is private, i.e., if you are the only person who is going
  694. Xto deposit revisions into it, strict locking is not needed and you
  695. Xcan turn it off.
  696. XIf strict locking is turned off,
  697. Xthe owner of the RCS file need not have a lock for check-in; all others
  698. Xstill do. Turning strict locking off and on is done with the commands
  699. X.PP
  700. X.ti 1.5i
  701. X.BR "rcs  \-U  f.c" "     and     " "rcs  \-L  f.c"
  702. X.PP
  703. XIf you don't want to clutter your working directory with RCS files, create 
  704. Xa subdirectory called RCS in your working directory, and move all your RCS 
  705. Xfiles there. RCS commands will look first into that directory to find 
  706. Xneeded files. All the commands discussed above will still work, without any 
  707. Xmodification. 
  708. X(Actually, pairs of RCS and working files can be specified in 3 ways:
  709. X(a) both are given, (b) only the working file is given, (c) only the
  710. XRCS file is given. Both RCS and working files may have arbitrary path prefixes;
  711. XRCS commands pair them up intelligently).
  712. X.PP
  713. XTo avoid the deletion of the working file during check-in (in case you want to
  714. Xcontinue editing), invoke
  715. X.PP
  716. X.ti 1.5i
  717. X.BR "ci  \-l  f.c" "     or     " "ci  \-u  f.c"
  718. X.PP
  719. XThese commands check in f.c as usual, but perform an implicit
  720. Xcheck-out. The first form also locks the checked in revision, the second one
  721. Xdoesn't. Thus, these options save you one check-out operation.
  722. XThe first form is useful if locking is strict, the second one if not strict.
  723. XBoth update the identification markers in your working file (see below).
  724. X.PP
  725. XYou can give \fIci\fR the number you want assigned to a checked in
  726. Xrevision. Assume all your revisions were numbered 1.1, 1.2, 1.3, etc.,
  727. Xand you would like to start release 2.
  728. XThe command
  729. X.PP
  730. X.ti 1.5i
  731. X.BR "ci  \-r2  f.c" "     or     " "ci  \-r2.1  f.c"
  732. X.PP
  733. Xassigns the number 2.1 to the new revision.
  734. XFrom then on, \fIci\fR will number the subsequent revisions
  735. Xwith 2.2, 2.3, etc. The corresponding \fIco\fR commands
  736. X.PP
  737. X.ti 1.5i
  738. X.BR "co  \-r2  f.c" "     and     " "co  \-r2.1  f.c"
  739. X.PP
  740. Xretrieve the latest revision numbered 2.x and the revision 2.1,
  741. Xrespectively. \fICo\fR without a revision number selects
  742. Xthe latest revision on the "trunk", i.e., the highest
  743. Xrevision with a number consisting of 2 fields. Numbers with more than 2
  744. Xfields are needed for branches.
  745. XFor example, to start a branch at revision 1.3, invoke
  746. X.PP
  747. X.ti 1.5i
  748. X.B "ci  \-r1.3.1  f.c
  749. X.PP
  750. XThis command starts a branch numbered 1 at revision 1.3, and assigns
  751. Xthe number 1.3.1.1 to the new revision. For more information about
  752. Xbranches, see \fIrcsfile\fR(5L).
  753. X.sp
  754. X.PP
  755. X.B "Automatic Identification"
  756. X.PP
  757. XRCS can put special strings for identification into your source and object
  758. Xcode. To obtain such identification, place the marker
  759. X.PP
  760. X.ti 1.5i
  761. X$\&Header$
  762. X.PP
  763. Xinto your text, for instance inside a comment.
  764. XRCS will replace this marker with a string of the form
  765. X.PP
  766. X.ti 1.5i
  767. X$\&Header:  filename  revision_number  date  time  author  state $
  768. X.PP
  769. XWith such a marker on the first page of each module, you can
  770. Xalways see with which revision you are working.
  771. XRCS keeps the markers up to date automatically.
  772. XTo propagate the markers into your object code, simply put
  773. Xthem into literal character strings. In C, this is done as follows:
  774. X.PP
  775. X.ti 1.5i
  776. Xstatic char rcsid[] = "$\&Header$";
  777. X.PP
  778. XThe command \fIident\fR extracts such markers from any file, even object code
  779. Xand dumps.
  780. XThus, \fIident\fR lets you find out
  781. Xwhich revisions of which modules were used in a given program. 
  782. X.PP
  783. XYou may also find it useful to put the marker $\&Log$
  784. Xinto your text, inside a comment. This marker accumulates
  785. Xthe log messages that are requested during check-in.
  786. XThus, you can maintain the complete history of your file directly inside it.
  787. XThere are several additional identification markers; see \fIco\fR(1L) for
  788. Xdetails.
  789. X.SH IDENTIFICATION
  790. X.de VL
  791. X\\$2
  792. X..
  793. XAuthor: Walter F. Tichy,
  794. XPurdue University, West Lafayette, IN, 47907.
  795. X.br
  796. XRevision Number:
  797. X.VL $Revision: 1.2 $
  798. X; Release Date:
  799. X.VL $Date: 89/05/02 11:17:54 $
  800. X\&.
  801. X.br
  802. XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
  803. X.SH SEE ALSO
  804. Xci(1L), co(1L), ident(1L), merge(1L), rcs(1L), rcsdiff(1L), rcsmerge(1L), rlog(1L),
  805. Xrcsfile(5L),
  806. X.br
  807. XWalter F. Tichy, "Design, Implementation, and Evaluation of a Revision Control
  808. XSystem," in \fIProceedings of the 6th International Conference on Software
  809. XEngineering\fR, IEEE, Tokyo, Sept. 1982.
  810. SHAR_EOF
  811. echo "extracting doc/rcsmerge.1l"
  812. sed 's/^X//' << \SHAR_EOF > doc/rcsmerge.1l
  813. X.TH RCSMERGE 1L "" "Purdue University"
  814. X.SH NAME
  815. Xrcsmerge \- merge RCS revisions
  816. X.SH SYNOPSIS
  817. X\fBrcsmerge\fR \fB\-r\fIrev1\fR [ \fB\-r\fIrev2\fR ] [ \fB\-p\fR ] file
  818. X.SH DESCRIPTION
  819. X.I Rcsmerge
  820. Xincorporates the changes between \fIrev1\fR and \fIrev2\fR of an
  821. XRCS file into the corresponding working file. If \fB\-p\fR is given, the result
  822. Xis printed on the standard output, otherwise the result overwrites the
  823. Xworking file.
  824. X.PP
  825. XA file name ending in ',v' is an RCS file name, otherwise a
  826. Xworking file name. \fIMerge\fR derives the working file name from the RCS
  827. Xfile name and vice versa, as explained in
  828. X.IR co (1L).
  829. XA pair consisting
  830. Xof both an RCS and a working file name may also be specified.
  831. X.PP
  832. X\fIRev1\fR may not be omitted. If \fIrev2\fR is omitted, the latest
  833. Xrevision on the default branch (normally the highest branch on the trunk)
  834. Xis assumed.
  835. XBoth \fIrev1\fR and \fIrev2\fR may be given numerically or symbolically.
  836. X.PP
  837. X\fIRcsmerge\fR prints a warning if there are overlaps, and delimits
  838. Xthe overlapping regions as explained in \fIco \-j\fR.
  839. XThe command is useful for incorporating changes into a checked-out revision.
  840. X.SH EXAMPLES
  841. XSuppose you have released revision 2.8 of f.c. Assume
  842. Xfurthermore that you just completed revision 3.4, when you receive
  843. Xupdates to release 2.8 from someone else.
  844. XTo combine the updates to 2.8 and your changes between 2.8 and 3.4,
  845. Xput the updates to 2.8 into file f.c and execute
  846. X.sp
  847. X.B "        rcsmerge  \-p  \-r2.8  \-r3.4  f.c  >f.merged.c
  848. X.sp
  849. XThen examine f.merged.c.
  850. XAlternatively, if you want to save the updates to 2.8 in the RCS file,
  851. Xcheck them in as revision 2.8.1.1 and execute \fIco \-j\fR:
  852. X.sp
  853. X.B "        ci  \-r2.8.1.1  f.c
  854. X.br
  855. X.B "        co  \-r3.4  \-j2.8:2.8.1.1  f.c
  856. X.sp
  857. XAs another example, the following command undoes the changes
  858. Xbetween revision 2.4 and 2.8 in your currently checked out revision
  859. Xin f.c.
  860. X.sp
  861. X.B "        rcsmerge  \-r2.8  \-r2.4  f.c
  862. X.sp
  863. XNote the order of the arguments, and that f.c will be
  864. Xoverwritten.
  865. X.SH IDENTIFICATION
  866. X.de VL
  867. X\\$2
  868. X..
  869. XAuthor: Walter F. Tichy,
  870. XPurdue University, West Lafayette, IN, 47907.
  871. X.sp 0
  872. XRevision Number:
  873. X.VL $Revision: 1.2 $
  874. X; Release Date:
  875. X.VL $Date: 89/05/02 11:18:34 $
  876. X\&.
  877. X.sp 0
  878. XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
  879. X.SH SEE ALSO
  880. Xci(1L), co(1L), merge(1L), ident(1L), rcs(1L), rcsdiff(1L), rlog(1L), rcsfile(5L),
  881. X.br
  882. XWalter F. Tichy, "Design, Implementation, and Evaluation of a Revision Control
  883. XSystem," in \fIProceedings of the 6th International Conference on Software
  884. XEngineering\fR, IEEE, Tokyo, Sept. 1982.
  885. X.SH BUGS
  886. X\fIRcsmerge\fR does not work on
  887. Xfiles that contain lines with a single `.'.
  888. SHAR_EOF
  889. echo "extracting doc/rlog.1l"
  890. sed 's/^X//' << \SHAR_EOF > doc/rlog.1l
  891. X.TH RLOG 1L "" "Purdue University"
  892. X.SH NAME
  893. Xrlog \- print log messages and other information about RCS files
  894. X.SH SYNOPSIS
  895. X.B rlog
  896. X[ options ]
  897. Xfile ...
  898. X.SH DESCRIPTION
  899. X.I Rlog
  900. Xprints information about RCS files.
  901. XFiles ending in `,v' are RCS files, all others are working files. If
  902. Xa working file is given, \fIrlog\fR tries to find the corresponding
  903. XRCS file first in directory ./RCS and then in the current directory,
  904. Xas explained in
  905. X.IR co (1L).
  906. X.PP
  907. X\fIRlog\fR prints the following information for each
  908. XRCS file: RCS file name, working file name, head (i.e., the number
  909. Xof the latest revision on the trunk), default branch, access list, locks,
  910. Xsymbolic names, suffix, total number of revisions, 
  911. Xnumber of revisions selected for printing, and 
  912. Xdescriptive text. This is followed by entries for the selected revisions in
  913. Xreverse chronological order for each branch. For each revision,
  914. X\fIrlog\fR prints revision number, author, date/time, state, number of
  915. Xlines added/deleted (with respect to the previous revision),
  916. Xlocker of the revision (if any), and log message.
  917. XWithout options, \fIrlog\fR prints complete information.
  918. XThe options below restrict this output.
  919. X.TP 10
  920. X.B \-L
  921. Xignores RCS files that have no locks set; convenient in combination with
  922. X\fB\-R\fR, \fB\-h\fR, or \fB\-l\fR.
  923. X.TP 10
  924. X.B \-R
  925. Xonly prints the name of the RCS file; convenient for translating a
  926. Xworking file name into an RCS file name.
  927. X.TP 10
  928. X.B \-h
  929. Xprints only RCS file name, working file name, head, 
  930. Xdefault branch, access list, locks,
  931. Xsymbolic names, and suffix.
  932. X.TP 10
  933. X.B \-t
  934. Xprints the same as \fB\-h\fR, plus the descriptive text.
  935. X.TP 10
  936. X.B \-b
  937. Xprints information about the revisions on the default branch (normally
  938. Xthe highest branch on the trunk).
  939. X.TP 10
  940. X.BI \-d "dates"
  941. Xprints information about revisions with a checkin date/time in the ranges given by
  942. Xthe semicolon-separated list of \fIdates\fR.
  943. XA range of the form \fId1<d2\fR or \fId2>d1\fR
  944. Xselects the revisions that were deposited between
  945. X\fId1\fR and \fId2\fR, (inclusive).
  946. XA range of the form \fI<d\fR or \fId>\fR selects
  947. Xall revisions dated
  948. X\fId\fR or earlier.
  949. XA range of the form \fId<\fR or \fI>d\fR selects
  950. Xall revisions dated \fId\fR or later.
  951. XA range of the form \fId\fR selects the single, latest revision dated \fId\fR or
  952. Xearlier.
  953. XThe date/time strings \fId, d1, \fRand \fId2\fR
  954. Xare in the free format explained in
  955. X.IR co (1L). 
  956. XQuoting is normally necessary, especially for \fI<\fR and \fI>\fR. Note that the separator is
  957. Xa semicolon.
  958. X.TP 10
  959. X.B \-l\fR[\fIlockers\fR]
  960. Xprints information about locked revisions.
  961. XIf the comma-separated list \fIlockers\fR of login names is given,
  962. Xonly the revisions locked by the given login names are printed.
  963. XIf the list is omitted, all locked revisions are printed.
  964. X.TP 10
  965. X.BI \-r "revisions"
  966. Xprints information about revisions given in the comma-separated list
  967. X\fIrevisions\fR of revisions and ranges. A range \fIrev1-rev2\fR means revisions
  968. X\fIrev1\fR to \fIrev2\fR on the same branch, \fI-rev\fR means revisions
  969. Xfrom the beginning of the branch up to and including \fIrev\fR,
  970. Xand \fIrev-\fR means revisions starting with \fIrev\fR to the end of the
  971. Xbranch containing \fIrev\fR. An argument that is a branch means all
  972. Xrevisions on that branch. A range of branches means all revisions
  973. Xon the branches in that range.
  974. X.TP 10
  975. X.BI \-s "states"
  976. Xprints information about revisions whose state attributes match one of the
  977. Xstates given in the comma-separated list \fIstates\fR.
  978. X.TP 10
  979. X.B \-w\fR[\fIlogins\fR]
  980. Xprints information about revisions checked in by users with 
  981. Xlogin names appearing in the comma-separated list \fIlogins\fR.
  982. XIf \fIlogins\fR is omitted, the user's login is assumed.
  983. X.PP
  984. X\fIRlog\fR prints the intersection of the revisions selected with
  985. Xthe options \fB\-d\fR, \fB\-l\fR, \fB\-s\fR, \fB\-w\fR, intersected
  986. Xwith the union of the revisions selected by \fB\-b\fR and \fB\-r\fR.
  987. X.SH EXAMPLES
  988. X.nf
  989. X.sp
  990. X        rlog  \-L  \-R  RCS/*,v
  991. X        rlog  \-L  \-h  RCS/*,v
  992. X        rlog  \-L  \-l  RCS/*,v
  993. X        rlog  RCS/*,v
  994. X.sp
  995. X.fi
  996. XThe first command prints the names of all RCS files in the subdirectory `RCS'
  997. Xwhich have locks. The second command prints the headers of those files,
  998. Xand the third prints the headers plus the log messages of the locked revisions.
  999. XThe last command prints complete information.
  1000. X.SH DIAGNOSTICS
  1001. XThe exit status always refers to the last RCS file operated upon,
  1002. Xand is 0 if the operation was successful, 1 otherwise.
  1003. X.SH IDENTIFICATION
  1004. X.de VL
  1005. X\\$2
  1006. X..
  1007. XAuthor: Walter F. Tichy,
  1008. XPurdue University, West Lafayette, IN, 47907.
  1009. X.sp 0
  1010. XRevision Number:
  1011. X.VL $Revision: 1.3 $
  1012. X; Release Date:
  1013. X.VL $Date: 89/05/02 11:19:20 $
  1014. X\&.
  1015. X.sp 0
  1016. XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
  1017. X.SH SEE ALSO
  1018. Xci(1L), co(1L), ident(1L), rcs(1L), rcsdiff(1L), rcsintro(1L), rcsmerge(1L),
  1019. Xrcsfile(5L)
  1020. X.br
  1021. XWalter F. Tichy, "Design, Implementation, and Evaluation of a Revision Control
  1022. XSystem," in \fIProceedings of the 6th International Conference on Software
  1023. XEngineering\fR, IEEE, Tokyo, Sept. 1982.
  1024. SHAR_EOF
  1025. if `test ! -d ked`
  1026. then
  1027.   mkdir ked
  1028.   echo "mkdir ked"
  1029. fi
  1030. echo "extracting ked/ked.c,v"
  1031. sed 's/^X//' << \SHAR_EOF > ked/ked.c,v
  1032. Xhead     1.5;
  1033. Xbranch   ;
  1034. Xaccess   ;
  1035. Xsymbols  ;
  1036. Xlocks    ; strict;
  1037. Xcomment  @ * @;
  1038. X
  1039. X
  1040. X1.5
  1041. Xdate     89.09.17.10.58.39;  author rick;  state Exp;
  1042. Xbranches ;
  1043. Xnext     1.4;
  1044. X
  1045. X1.4
  1046. Xdate     89.09.04.18.52.56;  author rick;  state Exp;
  1047. Xbranches ;
  1048. Xnext     1.3;
  1049. X
  1050. X1.3
  1051. Xdate     89.09.01.11.02.22;  author rick;  state Exp;
  1052. Xbranches ;
  1053. Xnext     1.2;
  1054. X
  1055. X1.2
  1056. Xdate     89.08.27.19.01.04;  author rick;  state Exp;
  1057. Xbranches ;
  1058. Xnext     1.1;
  1059. X
  1060. X1.1
  1061. Xdate     89.08.27.17.44.11;  author rick;  state Exp;
  1062. Xbranches ;
  1063. Xnext     ;
  1064. X
  1065. X
  1066. Xdesc
  1067. X@Initial checkin
  1068. X@
  1069. X
  1070. X
  1071. X1.5
  1072. Xlog
  1073. X@Cleanup so no errors when compiled with Lattice C
  1074. X@
  1075. Xtext
  1076. X@/* ed - standard editor        Authors: Brian Beattie, Kees Bot, and others */
  1077. X
  1078. X/* Modifications for Amiga made by Rick Schaeffer */
  1079. X
  1080. X/*
  1081. X * Copyright 1987 Brian Beattie Rights Reserved.
  1082. X *
  1083. X * Permission to copy and/or distribute granted under the
  1084. X * following conditions:
  1085. X *
  1086. X * 1). No charge may be made other than reasonable charges
  1087. X *    for reproduction.
  1088. X *
  1089. X * 2). This notice must remain intact.
  1090. X *
  1091. X * 3). No further restrictions may be added.
  1092. X *
  1093. X */
  1094. X
  1095. X/*    This program used to be in many little pieces, with this makefile:
  1096. X.SUFFIXES:    .c .s
  1097. X
  1098. XCFLAGS = -F 
  1099. X
  1100. XOBJS =    append.s catsub.s ckglob.s deflt.s del.s docmd.s doglob.s\
  1101. X    doprnt.s doread.s dowrite.s ed.s egets.s find.s getfn.s getlst.s\
  1102. X    getnum.s getone.s getptr.s getrhs.s gettxt.s ins.s join.s maksub.s\
  1103. X    move.s optpat.s set.s setbuf.s subst.s getpat.s matchs.s amatch.s\
  1104. X    unmkpat.s omatch.s makepat.s bitmap.s dodash.s esc.s system.s
  1105. X
  1106. Xed:    $(OBJS)
  1107. X    cc -T. -i -o ed $(OBJS)
  1108. X*/
  1109. X
  1110. X#include <stdio.h>
  1111. X#include <ios1.h>
  1112. X/****************************/
  1113. X
  1114. X/*    tools.h    */
  1115. Xstatic char    tools_h[] =
  1116. X"$Header: Rodime:ricks/rcs2/src/ked/ked.c,v 1.4 89/09/04 18:52:56 rick Exp Locker: rick $";
  1117. X/*
  1118. X *    #defines for non-printing ASCII characters
  1119. X */
  1120. X
  1121. X#define NUL    0x00    /* ^@@ */
  1122. X#define EOS    0x00    /* end of string */
  1123. X#define SOH    0x01    /* ^A */
  1124. X#define STX    0x02    /* ^B */
  1125. X#define ETX    0x03    /* ^C */
  1126. X#define EOT    0x04    /* ^D */
  1127. X#define ENQ    0x05    /* ^E */
  1128. X#define ACK    0x06    /* ^F */
  1129. X#define BEL    0x07    /* ^G */
  1130. X#define BS    0x08    /* ^H */
  1131. X#define HT    0x09    /* ^I */
  1132. X#define LF    0x0a    /* ^J */
  1133. X#define NL    '\n'
  1134. X#define VT    0x0b    /* ^K */
  1135. X#define FF    0x0c    /* ^L */
  1136. X#define CR    0x0d    /* ^M */
  1137. X#define SO    0x0e    /* ^N */
  1138. X#define SI    0x0f    /* ^O */
  1139. X#define DLE    0x10    /* ^P */
  1140. X#define DC1    0x11    /* ^Q */
  1141. X#define DC2    0x12    /* ^R */
  1142. X#define DC3    0x13    /* ^S */
  1143. X#define DC4    0x14    /* ^T */
  1144. X#define NAK    0x15    /* ^U */
  1145. X#define SYN    0x16    /* ^V */
  1146. X#define ETB    0x17    /* ^W */
  1147. X#define CAN    0x18    /* ^X */
  1148. X#define EM    0x19    /* ^Y */
  1149. X#define SUB    0x1a    /* ^Z */
  1150. X#define ESC    0x1b    /* ^[ */
  1151. X#define FS    0x1c    /* ^\ */
  1152. X#define GS    0x1d    /* ^] */
  1153. X#define RS    0x1e    /* ^^ */
  1154. X#define US    0x1f    /* ^_ */
  1155. X#define SP    0x20    /* space */
  1156. X#define DEL    0x7f    /* DEL*/
  1157. X
  1158. X
  1159. X#define TRUE    1
  1160. X#define FALSE    0
  1161. X#define ERR    -2
  1162. X
  1163. X
  1164. X/*    Definitions of meta-characters used in pattern matching
  1165. X *    routines.  LITCHAR & NCCL are only used as token identifiers;
  1166. X *    all the others are also both token identifier and actual symbol
  1167. X *    used in the regular expression.
  1168. X */
  1169. X
  1170. X
  1171. X#define BOL    '^'
  1172. X#define EOL    '$'
  1173. X#define ANY    '.'
  1174. X#define LITCHAR    'L'
  1175. X#define    ESCAPE    '\\'
  1176. X#define CCL    '['    /* Character class: [...] */
  1177. X#define CCLEND    ']'
  1178. X#define NEGATE    '~'
  1179. X#define NCCL    '!'    /* Negative character class [^...] */
  1180. X#define CLOSURE    '*'
  1181. X#define OR_SYM    '|'
  1182. X#define DITTO    '&'
  1183. X#define OPEN    '('
  1184. X#define CLOSE    ')'
  1185. X
  1186. X/* Largest permitted size for an expanded character class.  (i.e. the class
  1187. X * [a-z] will expand into 26 symbols; [a-z0-9] will expand into 36.)
  1188. X */
  1189. X#define CLS_SIZE    128
  1190. X
  1191. X/*
  1192. X *    Tokens are used to hold pattern templates. (see makepat())
  1193. X */
  1194. Xtypedef    char    BITMAP;
  1195. X
  1196. Xtypedef struct token {
  1197. X    char        tok;
  1198. X    char        lchar;
  1199. X    BITMAP        *bitmap;
  1200. X    struct token    *next;
  1201. X} TOKEN;
  1202. X
  1203. X#define TOKSIZE sizeof (TOKEN)
  1204. X
  1205. X/*
  1206. X *    An absolute maximun for strings.
  1207. X */
  1208. X
  1209. X#define MAXSTR    132    /* Maximum numbers of characters in a line */
  1210. X
  1211. X
  1212. Xextern    char    *matchs();
  1213. Xextern    char    *amatch();
  1214. Xextern    char    *in_string();
  1215. Xextern    TOKEN    *getpat();
  1216. Xextern    int    esc();
  1217. Xextern    char    *dodash();
  1218. Xextern    TOKEN    *makepat();
  1219. Xextern    void    unmakepat();
  1220. Xextern    int    insert();
  1221. Xextern    int    delete();
  1222. Xextern    int    isalphanum();
  1223. Xextern    char    *stoupper();
  1224. Xextern    int    pr_tok();
  1225. Xextern    int    pr_line();
  1226. Xextern    BITMAP    *makebitmap();
  1227. X
  1228. X/* macros */
  1229. X#define toupper(c)    (c>='a'&&c<='z'?c-32:c)
  1230. X
  1231. X/*    ed.h    */
  1232. X#define FATAL    (ERR-1)
  1233. Xstruct    line {
  1234. X    int        l_stat;        /* empty, mark */
  1235. X    struct line    *l_prev;
  1236. X    struct line    *l_next;
  1237. X    char        l_buff[1];
  1238. X};
  1239. X
  1240. Xtypedef struct line    LINE;
  1241. X
  1242. X#define LINFREE    1    /* entry not in use */
  1243. X#define LGLOB    2       /* line marked global */
  1244. X
  1245. X#define MAXLINE    256    /* max number of chars per line */
  1246. X#define MAXPAT    256    /* max number of chars per replacement pattern */
  1247. X#define MAXFNAME 256    /* max file name size */
  1248. X
  1249. Xextern LINE    line0;
  1250. Xextern int    curln, lastln, line1, line2, nlines;
  1251. Xextern int    nflg;        /* print line number flag */
  1252. Xextern int    lflg;        /* print line in verbose mode */
  1253. Xextern int    pflg;        /* print current line after each command */
  1254. Xextern char    *inptr;            /* tty input buffer */
  1255. Xextern char    linbuf[], *linptr;    /* current line */
  1256. Xextern int    truncflg;    /* truncate long line flag */
  1257. Xextern int    eightbit;    /* save eighth bit */
  1258. Xextern int    nonascii;    /* count of non-ascii chars read */
  1259. Xextern int    nullchar;    /* count of null chars read */
  1260. Xextern int    truncated;    /* count of lines truncated */
  1261. Xextern int    fchanged;    /* file changed */
  1262. X
  1263. X#define nextln(l)    ((l)+1 > lastln ? 0 : (l)+1)
  1264. X#define prevln(l)    ((l)-1 < 0 ? lastln : (l)-1)
  1265. X
  1266. Xextern char    *getfn();
  1267. Xextern LINE    *getptr();
  1268. Xextern char    *gettxt();
  1269. Xextern char    *maksub();
  1270. Xextern TOKEN    *optpat();
  1271. X
  1272. Xextern char    *catsub();
  1273. X
  1274. Xextern char    *strcpy();
  1275. Xextern int    *malloc();
  1276. Xextern void putcntl(),prntln(),relink(),clrbuf(),edsetbuf();
  1277. X
  1278. X/*    amatch.c    */
  1279. X/* #include <stdio.h> */
  1280. X/* #include "tools.h" */
  1281. X
  1282. X/*     Scans throught the pattern template looking for a match
  1283. X * with lin.  Each element of lin is compared with the template
  1284. X * until either a mis-match is found or the end of the template
  1285. X * is reached.  In the former case a 0 is returned; in the latter,
  1286. X * a pointer into lin (pointing to the character following the
  1287. X * matched pattern) is returned.
  1288. X *
  1289. X *    "lin"    is a pointer to the line being searched.
  1290. X *    "pat"    is a pointer to a template made by makepat().
  1291. X *    "boln"    is a pointer into "lin" which points at the
  1292. X *            character at the beginning of the line.
  1293. X */
  1294. X
  1295. Xchar *paropen[9], *parclose[9];
  1296. Xint between, parnum;
  1297. Xstatic char *match();
  1298. X
  1299. Xchar    *
  1300. Xamatch(lin, pat, boln)
  1301. Xchar    *lin;
  1302. XTOKEN    *pat;
  1303. Xchar    *boln;
  1304. X{
  1305. X
  1306. X    between=0;
  1307. X    parnum=0;
  1308. X
  1309. X    lin=match(lin, pat, boln);
  1310. X
  1311. X    if (between) return 0;
  1312. X
  1313. X    while (parnum<9) {
  1314. X        paropen[parnum] = parclose[parnum] = "";
  1315. X        parnum++;
  1316. X    }
  1317. X    return lin;
  1318. X}
  1319. X
  1320. Xstatic char    *
  1321. Xmatch(lin, pat, boln)
  1322. Xchar    *lin;
  1323. XTOKEN    *pat;
  1324. Xchar    *boln;
  1325. X{
  1326. X    register char    *bocl, *rval, *strstart;
  1327. X
  1328. X    if(pat == 0)
  1329. X        return 0;
  1330. X
  1331. X    strstart = lin;
  1332. X
  1333. X    while(pat)
  1334. X    {
  1335. X        if(pat->tok == CLOSURE && pat->next)
  1336. X        {
  1337. X                /* Process a closure:
  1338. X                 * first skip over the closure token to the
  1339. X                 * object to be repeated.  This object can be
  1340. X                 * a character class.
  1341. X                 */
  1342. X
  1343. X            pat = pat->next;
  1344. X
  1345. X                /* Now match as many occurrences of the
  1346. X                 * closure pattern as possible.
  1347. X                 */
  1348. X            bocl = lin;
  1349. X
  1350. X            while( *lin && omatch(&lin, pat))
  1351. X                ;
  1352. X
  1353. X                /* 'Lin' now points to the character that made
  1354. X                 * made us fail.  Now go on to process the
  1355. X                 * rest of the string.  A problem here is
  1356. X                 * a character following the closure which
  1357. X                 * could have been in the closure.
  1358. X                 * For example, in the pattern "[a-z]*t" (which
  1359. X                 * matches any lower-case word ending in a t),
  1360. X                 * the final 't' will be sucked up in the while
  1361. X                 * loop.  So, if the match fails, we back up a
  1362. X                 * notch and try to match the rest of the
  1363. X                 * string again, repeating this process
  1364. X                 * recursively until we get back to the
  1365. X                 * beginning of the closure.  The recursion
  1366. X                 * goes, at most two levels deep.
  1367. X                 */
  1368. X
  1369. X            if(pat = pat->next)
  1370. X            {
  1371. X                int savbtwn=between;
  1372. X                int savprnm=parnum;
  1373. X
  1374. X                while(bocl <= lin)
  1375. X                {
  1376. X                    if(rval = match(lin, pat, boln))
  1377. X                    {
  1378. X                            /* success */
  1379. X                        return(rval);
  1380. X                    } else {
  1381. X                        --lin;
  1382. X                        between=savbtwn;
  1383. X                        parnum=savprnm;
  1384. X                    }
  1385. X                }
  1386. X                return (0);    /* match failed */
  1387. X            }
  1388. X        } else
  1389. X        if (pat->tok == OPEN)
  1390. X        {
  1391. X            if (between || parnum>=9) return 0;
  1392. X            paropen[parnum] = lin;
  1393. X            between=1;
  1394. X            pat = pat->next;
  1395. X        } else
  1396. X        if (pat->tok == CLOSE)
  1397. X        {
  1398. X            if (!between) return 0;
  1399. X            parclose[parnum++] = lin;
  1400. X            between=0;
  1401. X            pat = pat->next;
  1402. X        } else
  1403. X        if (omatch(&lin, pat, boln))
  1404. X        {
  1405. X            pat = pat->next;
  1406. X        } else {
  1407. X            return (0);
  1408. X        }
  1409. X    }
  1410. X        /* Note that omatch() advances lin to point at the next
  1411. X         * character to be matched.  Consequently, when we reach
  1412. X         * the end of the template, lin will be pointing at the
  1413. X         * character following the last character matched.  The
  1414. X         * exceptions are templates containing only a BOLN or EOLN
  1415. X         * token.  In these cases omatch doesn't advance.
  1416. X         *
  1417. X         * A philosophical point should be mentioned here.  Is $
  1418. X         * a position or a character? (i.e. does $ mean the EOL
  1419. X         * character itself or does it mean the character at the end
  1420. X         * of the line.)  I decided here to make it mean the former,
  1421. X         * in order to make the behavior of match() consistent.  If
  1422. X         * you give match the pattern ^$ (match all lines consisting
  1423. X         * only of an end of line) then, since something has to be
  1424. X         * returned, a pointer to the end of line character itself is
  1425. X         * returned.
  1426. X         */
  1427. X
  1428. X    return ((char *)max(strstart , lin));
  1429. X}
  1430. X
  1431. X/*    append.c    */
  1432. X/* #include <stdio.h> */
  1433. X/* #include "tools.h" */
  1434. X/* #include "ed.h" */
  1435. X
  1436. Xappend(line, glob)
  1437. Xint    line, glob;
  1438. X{
  1439. X    int    stat;
  1440. X    char    lin[MAXLINE];
  1441. X
  1442. X    if(glob)
  1443. X        return(ERR);
  1444. X    curln = line;
  1445. X    while(1)
  1446. X    {
  1447. X        if(nflg)
  1448. X            printf("%d\t",curln+1);
  1449. X
  1450. X        if(fgets(lin, MAXLINE, stdin) == NULL)
  1451. X            return( EOF );
  1452. X        if(lin[0] == '.' && lin[1] == '\n')
  1453. X            return(0);
  1454. X        stat = ins(lin);
  1455. X        if(stat < 0)
  1456. X            return( ERR );
  1457. X        
  1458. X    }
  1459. X}
  1460. X
  1461. X/*    bitmap.c    */
  1462. X/*
  1463. X *    BITMAP.C -    makebitmap, setbit, testbit
  1464. X *            bit-map manipulation routines.
  1465. X *
  1466. X *    Copyright (c) Allen I. Holub, all rights reserved.  This program may
  1467. X *        for copied for personal, non-profit use only.
  1468. X *
  1469. X */
  1470. X#ifdef DEBUG
  1471. X/* #include <stdio.h> */
  1472. X#endif
  1473. X/* #include "tools.h" */
  1474. X
  1475. XBITMAP    *makebitmap( size )
  1476. Xunsigned size;
  1477. X{
  1478. X    /*    Make a bit map with "size" bits.  The first entry in
  1479. X     *    the map is an "unsigned int" representing the maximum
  1480. X     *    bit.  The map itself is concatenated to this integer.
  1481. X     *    Return a pointer to a map on success, 0 if there's
  1482. X     *    not enough memory.
  1483. X     */
  1484. X
  1485. X    unsigned *map, numbytes;
  1486. X
  1487. X    numbytes = (size >> 3) + ((size & 0x07) ? 1 : 0 );
  1488. X
  1489. X#ifdef DEBUG
  1490. X    printf("Making a %d bit map (%d bytes required)\n", size, numbytes);
  1491. X#endif
  1492. X
  1493. X    if( map = (unsigned *) malloc( numbytes + sizeof(unsigned) ))
  1494. X        *map = size;
  1495. X
  1496. X    return ((BITMAP *)map);
  1497. X}
  1498. X
  1499. Xsetbit( c, map, val )
  1500. Xunsigned    c, val;
  1501. Xchar        *map;
  1502. X{
  1503. X    /*    Set bit c in the map to val.
  1504. X     *    If c > map-size, 0 is returned, else 1 is returned.
  1505. X     */
  1506. X
  1507. X    if( c >= *(unsigned *)map )    /* if c >= map size */
  1508. X        return 0;
  1509. X
  1510. X    map += sizeof(unsigned);    /* skip past size */
  1511. X    
  1512. X    if( val )
  1513. X        map[c >> 3] |= 1 << (c & 0x07);
  1514. X    else
  1515. X        map[c >> 3] &= ~(1 << (c & 0x07));
  1516. X
  1517. X    return( 1 );
  1518. X}
  1519. X
  1520. Xtestbit( c, map )
  1521. Xunsigned    c;
  1522. Xchar        *map;
  1523. X{
  1524. X    /*    Return 1 if the bit corresponding to c in map is set.
  1525. X     *    0 if it is not.
  1526. X     */
  1527. X
  1528. X    if( c >= *(unsigned *)map )
  1529. X        return 0;
  1530. X
  1531. X    map += sizeof(unsigned);
  1532. X    
  1533. X    return(map[ c >> 3 ] & (1 << (c & 0x07)));
  1534. X}
  1535. X
  1536. X/*    catsub.c    */
  1537. X/* #include <stdio.h> */
  1538. X/* #include "tools.h" */
  1539. X/* #include "ed.h" */
  1540. X
  1541. Xextern char *paropen[9], *parclose[9];
  1542. X
  1543. Xchar    *
  1544. Xcatsub(from, to, sub, new, newend)
  1545. Xchar    *from, *to, *sub, *new, *newend;
  1546. X{
  1547. X    char    *cp, *cp2;
  1548. X
  1549. X    for(cp = new; *sub != EOS && cp < newend;)
  1550. X    {
  1551. X        if(*sub == DITTO)
  1552. X            for(cp2 = from; cp2 < to;)
  1553. X            {
  1554. X                *cp++ = *cp2++;
  1555. X                if(cp >= newend)
  1556. X                    break;
  1557. X            }
  1558. X        else
  1559. X        if (*sub == ESCAPE) {
  1560. X            sub++;
  1561. X            if ('1' <= *sub && *sub <= '9') {
  1562. X                char *parcl = parclose[*sub - '1'];
  1563. X
  1564. X                for (cp2 = paropen[*sub - '1']; cp2 < parcl;)
  1565. X                {
  1566. X                    *cp++ = *cp2++;
  1567. X                    if (cp >= newend) break;
  1568. X                }
  1569. X            } else
  1570. X                *cp++ = *sub;
  1571. X        } else
  1572. X            *cp++ = *sub;
  1573. X
  1574. X        sub++;
  1575. X    }
  1576. X
  1577. X    return(cp);
  1578. X}
  1579. X
  1580. X/*    ckglob.c    */
  1581. X/* #include <stdio.h> */
  1582. X/* #include "tools.h" */
  1583. X/* #include "ed.h" */
  1584. X
  1585. Xckglob()
  1586. X{
  1587. X    TOKEN    *glbpat;
  1588. X    char    c, delim, *lin;
  1589. X    int    num;
  1590. X    LINE    *ptr;
  1591. X
  1592. X    c = *inptr;
  1593. X
  1594. X    if(c != 'g' && c != 'v')
  1595. X        return(0);
  1596. X
  1597. X    if (deflt(1, lastln) < 0)
  1598. X        return(ERR);
  1599. X
  1600. X    delim = *++inptr;
  1601. X    if(delim <= ' ')
  1602. X        return(ERR);
  1603. X
  1604. X    glbpat = optpat();
  1605. X
  1606. X    if(*inptr == delim)
  1607. X        inptr++;
  1608. X
  1609. X    for (num=1; num<=lastln; num++)
  1610. X    {
  1611. X        ptr = getptr(num);
  1612. X        ptr->l_stat &= ~LGLOB;
  1613. X        if (line1 <= num && num <= line2) {
  1614. X            lin = gettxt(num);
  1615. X            if(matchs(lin, glbpat, 0)) {
  1616. X                if (c=='g') ptr->l_stat |= LGLOB;
  1617. X            } else {
  1618. X                if (c=='v') ptr->l_stat |= LGLOB;
  1619. X            }
  1620. X        }
  1621. X    }
  1622. X    return(1);
  1623. X}
  1624. X
  1625. X/*    deflt.c    */
  1626. X/* #include <stdio.h> */
  1627. X/* #include "tools.h" */
  1628. X/* #include "ed.h" */
  1629. X
  1630. Xdeflt(def1, def2)
  1631. Xint    def1, def2;
  1632. X{
  1633. X    if(nlines == 0)
  1634. X    {
  1635. X        line1 = def1;
  1636. X        line2 = def2;
  1637. X    }
  1638. X    if(line1 > line2 || line1 <= 0)
  1639. X        return (ERR);
  1640. X}
  1641. X
  1642. X/*    del.c    */
  1643. X/* #include <stdio.h> */
  1644. X/* #include "tools.h" */
  1645. X/* #include "ed.h" */
  1646. X
  1647. Xdel(from, to)
  1648. Xint    from, to;
  1649. X{
  1650. X    LINE    *first, *last, *next, *tmp;
  1651. X
  1652. X    if(from < 1)
  1653. X        from = 1;
  1654. X    first = getptr(prevln(from));
  1655. X    last = getptr(nextln(to));
  1656. X    next = first->l_next;
  1657. X    while(next != last && next != &line0)
  1658. X    {
  1659. X        tmp = next->l_next;
  1660. X        free(next);
  1661. X        next = tmp;
  1662. X    }
  1663. X    relink(first, last, first, last);
  1664. X    lastln -= (to - from)+1;
  1665. X    curln = prevln(from);
  1666. X    return(1);
  1667. X}
  1668. X
  1669. X/*    docmd.c    */
  1670. X/* #include <stdio.h> */
  1671. X/* #include "tools.h" */
  1672. X/* #include "ed.h" */
  1673. X
  1674. Xchar    fname[MAXFNAME];
  1675. Xint    fchanged;
  1676. Xextern int nofname;
  1677. Xextern int prompt;
  1678. Xextern    int mark[];
  1679. X
  1680. Xdocmd(glob)
  1681. Xint    glob;
  1682. X{
  1683. X    static char    rhs[MAXPAT];
  1684. X    TOKEN    *subpat;
  1685. X    int    c, err, line3;
  1686. X    int    apflg, pflag, gflag;
  1687. X    int    nchng;
  1688. X    char    *fptr;
  1689. X
  1690. X    pflag = FALSE;
  1691. X    while(*inptr == SP && *inptr == HT)
  1692. X        inptr++;
  1693. X
  1694. X    c = *inptr++;
  1695. X
  1696. X    switch(c)
  1697. X    {
  1698. X    case NL:                    /* print next line */
  1699. X        if(nlines == 0)
  1700. X        {
  1701. X            if ((line2 = nextln(curln))==0)
  1702. X                return(ERR);
  1703. X        }
  1704. X        curln = line2;
  1705. X        return (1);
  1706. X        break;
  1707. X
  1708. X    case '=':                    /* print current line number */
  1709. X        printf("%d\n",line2);
  1710. X        break;
  1711. X
  1712. X    case 'a':                    /* append lines */
  1713. X        if(*inptr != NL || nlines > 1)
  1714. X            return(ERR);
  1715. X
  1716. X        if(append(line1, glob) < 0)
  1717. X            return(ERR);;
  1718. X        fchanged = TRUE;
  1719. X        break;
  1720. X
  1721. X    case 'c':                    /* changed lines */
  1722. X        if(*inptr != NL)
  1723. X            return(ERR);
  1724. X
  1725. X        if(deflt(curln, curln) < 0)
  1726. X            return(ERR);
  1727. X
  1728. X        if(del(line1, line2) < 0)
  1729. X            return(ERR);
  1730. X        if(append(curln, glob) < 0)
  1731. X            return(ERR);
  1732. X        fchanged = TRUE;
  1733. X        break;
  1734. X
  1735. X    case 'd':                    /* delete lines */
  1736. X        if(*inptr != NL)
  1737. X            return(ERR);
  1738. X
  1739. X        if(deflt(curln, curln) < 0)
  1740. X            return(ERR);
  1741. X
  1742. X        if(del(line1, line2) < 0)
  1743. X            return(ERR);
  1744. X        if(nextln(curln) != 0)
  1745. X            curln = nextln(curln);
  1746. X        fchanged = TRUE;
  1747. X        break;
  1748. X
  1749. X    case 'e':                    /* edit new file with change check */
  1750. X        if(nlines > 0)
  1751. X            return(ERR);
  1752. X        if(fchanged) {
  1753. X            fchanged = FALSE;
  1754. X            return(ERR);
  1755. X        }
  1756. X        /*FALL THROUGH*/
  1757. X    case 'E':                    /* edit new file no check */
  1758. X        if(nlines > 0)
  1759. X            return(ERR);
  1760. X
  1761. X        if(*inptr != ' ' && *inptr != HT && *inptr != NL)
  1762. X            return(ERR);
  1763. X
  1764. X        if((fptr = getfn()) == NULL)
  1765. X            return(ERR);
  1766. X
  1767. X        clrbuf();
  1768. X        if((err = doread(0, fptr)) < 0)
  1769. X            return(err);
  1770. X
  1771. X        strcpy(fname, fptr);
  1772. X        fchanged = FALSE;
  1773. X        break;
  1774. X
  1775. X    case 'f':                    /* set or display current file name */
  1776. X        if(nlines > 0)
  1777. X            return(ERR);
  1778. X
  1779. X        if(*inptr != ' ' && *inptr != HT && *inptr != NL)
  1780. X            return(ERR);
  1781. X
  1782. X        if((fptr = getfn()) == NULL)
  1783. X            return(ERR);
  1784. X
  1785. X        if (nofname)
  1786. X            printf("%s\n", fname);
  1787. X        else
  1788. X            strcpy(fname, fptr);
  1789. X        break;
  1790. X
  1791. X    case 'H':
  1792. X    case 'h':                    /* print last error */
  1793. X        return(ERR);
  1794. X        break;
  1795. X
  1796. X    case 'i':                    /* insert lines */
  1797. X        if(*inptr != NL || nlines > 1)
  1798. X            return(ERR);
  1799. X
  1800. X        if(append(prevln(line1), glob) < 0)
  1801. X            return(ERR);
  1802. X        fchanged = TRUE;
  1803. X        break;
  1804. X
  1805. X    case 'j':                    /* join lines */
  1806. X        if (*inptr != NL || deflt(curln, curln+1)<0)
  1807. X            return(ERR);
  1808. X
  1809. X        if (join(line1, line2) < 0)
  1810. X            return(ERR);
  1811. X        break;
  1812. X
  1813. X    case 'k':                    /* mark line address */
  1814. X        while (*inptr == ' ' || *inptr == HT) inptr++;
  1815. X
  1816. X        if (*inptr < 'a' || *inptr > 'z')
  1817. X            return ERR;
  1818. X        c= *inptr++;
  1819. X
  1820. X        if(*inptr != ' ' && *inptr != HT && *inptr != NL)
  1821. X            return(ERR);
  1822. X
  1823. X        mark[c-'a'] = line1;
  1824. X        break;
  1825. X
  1826. X    case 'L':                    /* toggle verbose print */
  1827. X        lflg = ~lflg;
  1828. X        break;
  1829. X
  1830. X    case 'l':                    /* print lines verbose */
  1831. X        if(*inptr != NL)
  1832. X            return(ERR);
  1833. X        if(deflt(curln,curln) < 0)
  1834. X            return(ERR);
  1835. X        if (dolst(line1,line2) < 0)
  1836. X            return(ERR);
  1837. X        break;
  1838. X
  1839. X    case 'm':                    /* move lines */
  1840. X        if((line3 = getone()) < 0)
  1841. X            return(ERR);
  1842. X        if(deflt(curln,curln) < 0)
  1843. X            return(ERR);
  1844. X        if(move(line3) < 0)
  1845. X            return(ERR);
  1846. X        fchanged = TRUE;
  1847. X        break;
  1848. X
  1849. X    case 'N':                    /* toggle print line numbers */
  1850. X        nflg = ~nflg;
  1851. X        break;
  1852. X
  1853. X    case 'n':                    /* print lines with numbers */
  1854. X        if(*inptr != NL)
  1855. X            return(ERR);
  1856. X        if(deflt(curln,curln) < 0)
  1857. X            return(ERR);
  1858. X        if (donum(line1,line2) < 0)
  1859. X            return(ERR);
  1860. X        break;
  1861. X
  1862. X    case 'P':                    /* toggle prompt */
  1863. X        prompt = ~prompt;
  1864. X        break;
  1865. X
  1866. X    case 'p':                    /* print lines */
  1867. X        if(*inptr != NL)
  1868. X            return(ERR);
  1869. X        if(deflt(curln,curln) < 0)
  1870. X            return(ERR);
  1871. X        if(doprnt(line1,line2) < 0)
  1872. X            return(ERR);
  1873. X        break;
  1874. X
  1875. X    case 'q':                    /* quit, check changed */
  1876. X        if(fchanged) {
  1877. X            fchanged = FALSE;
  1878. X            return(ERR);
  1879. X        }
  1880. X        /*FALL THROUGH*/
  1881. X    case 'Q':                    /* quit, no check for change */
  1882. X        if(*inptr == NL && nlines == 0 && !glob)
  1883. X            return(EOF);
  1884. X        else
  1885. X            return(ERR);
  1886. X
  1887. X    case 'r':                    /* read in file */
  1888. X        if(nlines > 1)
  1889. X            return(ERR);
  1890. X
  1891. X        if(nlines == 0)
  1892. X            line2 = lastln;
  1893. X
  1894. X        if(*inptr != ' ' && *inptr != HT && *inptr != NL)
  1895. X            return(ERR);
  1896. X
  1897. X        if((fptr = getfn()) == NULL)
  1898. X            return(ERR);
  1899. X
  1900. X        if((err = doread(line2, fptr)) < 0)
  1901. X            return(err);
  1902. X        fchanged = TRUE;
  1903. X        break;
  1904. X
  1905. X    case 's':                    /* substitute, set */
  1906. X        if(*inptr == 'e')
  1907. X            return(set());
  1908. X        while(*inptr == SP || *inptr == HT)
  1909. X            inptr++;
  1910. X        if((subpat = optpat()) == NULL)
  1911. X            return(ERR);
  1912. X        if((gflag = getrhs(rhs)) < 0)
  1913. X            return(ERR);
  1914. X        if(*inptr == 'p')
  1915. X            pflag++;
  1916. X        if(deflt(curln, curln) < 0)
  1917. X            return(ERR);
  1918. X        if((nchng = subst(subpat, rhs, gflag, pflag)) < 0)
  1919. X            return(ERR);
  1920. X        if(nchng)
  1921. X            fchanged = TRUE;
  1922. X        break;
  1923. X
  1924. X    case 't':                    /* copy lines */
  1925. X        if((line3 = getone()) < 0)
  1926. X            return(ERR);
  1927. X        if(deflt(curln,curln) < 0)
  1928. X            return(ERR);
  1929. X        if(transfer(line3) < 0)
  1930. X            return(ERR);
  1931. X        fchanged = TRUE;
  1932. X        break;
  1933. X
  1934. X    case 'u':                    /* undo last command */
  1935. X        return(ERR);
  1936. X        break;
  1937. X
  1938. X    case 'W':                    /* write append */
  1939. X    case 'w':                    /* write */ 
  1940. X        apflg = (c=='W');
  1941. X
  1942. X        if(*inptr != ' ' && *inptr != HT && *inptr != NL)
  1943. X            return(ERR);
  1944. X
  1945. X        if((fptr = getfn()) == NULL)
  1946. X            return(ERR);
  1947. X
  1948. X        if(deflt(1, lastln) < 0)
  1949. X            return(ERR);
  1950. X        if(dowrite(line1, line2, fptr, apflg) < 0)
  1951. X            return(ERR);
  1952. X        fchanged = FALSE;
  1953. X        break;
  1954. X
  1955. X    case 'x':                    /* write then quit */
  1956. X        if(*inptr == NL && nlines == 0 && !glob)
  1957. X        {
  1958. X            if((fptr = getfn()) == NULL)
  1959. X                return(ERR);
  1960. X            if(dowrite(1, lastln, fptr, 0) >= 0)
  1961. X                return(EOF);
  1962. X        }
  1963. X        return(ERR);
  1964. X
  1965. X    case 'z':                    /* print +21, -21, -11.+10 lines */
  1966. X        if(deflt(curln,curln) < 0)
  1967. X            return(ERR);
  1968. X
  1969. X        switch(*inptr)
  1970. X        {
  1971. X        case '-':
  1972. X            if(doprnt(line1-21,line1) < 0)
  1973. X                return(ERR);
  1974. X            break;
  1975. X
  1976. X        case '.':
  1977. X            if(doprnt(line1-11,line1+10) < 0)
  1978. X                return(ERR);
  1979. X            break;
  1980. X
  1981. X        case '+':
  1982. X        case '\n':
  1983. X            if(doprnt(line1,line1+21) < 0)
  1984. X                return(ERR);
  1985. X            break;
  1986. X        }
  1987. X        break;
  1988. X
  1989. X    default:
  1990. X        return(ERR);
  1991. X    }
  1992. X    return (0);
  1993. X}
  1994. X
  1995. Xint dolst(line1, line2) int line1, line2;
  1996. X{
  1997. X    int oldlflg=lflg, p;
  1998. X
  1999. X    lflg=1;
  2000. X    p=doprnt(line1, line2);
  2001. X    lflg=oldlflg;
  2002. X
  2003. X    return p;
  2004. X}
  2005. X
  2006. Xint donum(line1, line2) int line1, line2;
  2007. X{
  2008. X    int oldnflg=nflg, p;
  2009. X
  2010. X    nflg=1;
  2011. X    p=doprnt(line1, line2);
  2012. X    nflg=oldnflg;
  2013. X
  2014. X    return p;
  2015. X}
  2016. X
  2017. X/*    dodash.c    */
  2018. X/* #include <stdio.h> */
  2019. X/* #include "tools.h" */
  2020. X
  2021. X/*    Expand the set pointed to by *src into dest.
  2022. X *    Stop at delim.  Return 0 on error or size of
  2023. X *    character class on success.  Update *src to
  2024. X *    point at delim.  A set can have one element
  2025. X *    {x} or several elements ( {abcdefghijklmnopqrstuvwxyz}
  2026. X *    and {a-z} are equivalent ).  Note that the dash
  2027. X *    notation is expanded as sequential numbers.
  2028. X *    This means (since we are using the ASCII character
  2029. X *    set) that a-Z will contain the entire alphabet
  2030. X *    plus the symbols: [\]^_`.  The maximum number of
  2031. X *    characters in a character class is defined by maxccl.
  2032. X */
  2033. Xchar *
  2034. Xdodash(delim, src, map)
  2035. X
  2036. Xint    delim;
  2037. Xchar    *src, *map;
  2038. X{
  2039. X
  2040. X    register int    first,    last;
  2041. X    char        *start;
  2042. X
  2043. X    start = src;
  2044. X
  2045. X    while( *src && *src != delim )
  2046. X    {
  2047. X        if( *src != '-')
  2048. X            setbit( esc( &src ), map, 1 );
  2049. X
  2050. X        else if( src == start || *(src + 1) == delim )
  2051. X            setbit( '-', map, 1 );
  2052. X        else {
  2053. X            src++;
  2054. X
  2055. X            if( *src < *(src - 2))
  2056. X            {
  2057. X                first = *src;
  2058. X                last = *(src - 2);
  2059. X            } else {
  2060. X                first = *(src - 2);
  2061. X                last = *src;
  2062. X            }
  2063. X
  2064. X            while( ++first <= last )
  2065. X                setbit( first, map, 1);
  2066. X
  2067. X        }
  2068. X        src++;
  2069. X    }
  2070. X    return( src );
  2071. X}
  2072. X
  2073. X/*    doglob.c    */
  2074. X/* #include <stdio.h> */
  2075. X/* #include "tools.h" */
  2076. X/* #include "ed.h" */
  2077. X
  2078. Xdoglob()
  2079. X{
  2080. X    int    lin, stat;
  2081. X    char    *cmd;
  2082. X    LINE    *ptr;
  2083. X
  2084. X    cmd = inptr;
  2085. X
  2086. X    while(1)
  2087. X    {
  2088. X        for (lin=1; lin<=lastln; lin++) {
  2089. X            ptr = getptr(lin);
  2090. X            if (ptr->l_stat & LGLOB) break;
  2091. X        }
  2092. X        if (lin>lastln) break;
  2093. X
  2094. X        ptr->l_stat &= ~LGLOB;
  2095. X        curln = lin;
  2096. X        inptr = cmd;
  2097. X        if((stat = getlst()) < 0)
  2098. X            return(stat);
  2099. X        if((stat = docmd(1)) < 0)
  2100. X            return(stat);
  2101. X    }
  2102. X    return(0);
  2103. X}
  2104. X
  2105. X/*    doprnt.c    */
  2106. X/* #include <stdio.h> */
  2107. X/* #include "tools.h" */
  2108. X/* #include "ed.h" */
  2109. X
  2110. Xdoprnt(from, to)
  2111. Xint    from, to;
  2112. X{
  2113. X    int    i;
  2114. X
  2115. X    from = from < 1 ? 1 : from;
  2116. X    to = to > lastln ? lastln : to;
  2117. X        
  2118. X    if(to != 0)
  2119. X    {
  2120. X        for(i = from; i <= to; i++)
  2121. X            prntln(gettxt(i), lflg, (nflg ? i : 0));
  2122. X        curln = to;
  2123. X    }
  2124. X
  2125. X    return(0);
  2126. X}
  2127. X
  2128. Xvoid prntln(str, vflg, lin)
  2129. Xchar    *str;
  2130. Xint    vflg, lin;
  2131. X{
  2132. X    if(lin)
  2133. X        printf("%d\t",lin);
  2134. X    while(*str && *str != NL)
  2135. X    {
  2136. X        if(*str < ' ' || *str >= 0x7f)
  2137. X        {
  2138. X            switch(*str)
  2139. X            {
  2140. X            case '\t':
  2141. X                if(vflg)
  2142. X                    putcntl(*str, stdout);
  2143. X                else
  2144. X                    putc(*str, stdout);
  2145. X                break;
  2146. X
  2147. X            case DEL:
  2148. X                putc('^', stdout);
  2149. X                putc('?', stdout);
  2150. X                break;
  2151. X
  2152. X            default:
  2153. X                putcntl(*str, stdout);
  2154. X                break;
  2155. X            }
  2156. X        } else
  2157. X            putc(*str, stdout);
  2158. X        str++;
  2159. X    }
  2160. X    if(vflg)
  2161. X        putc('$',stdout);
  2162. X    putc('\n', stdout);
  2163. X}
  2164. X
  2165. Xvoid putcntl(c, stream)
  2166. Xchar    c;
  2167. XFILE    *stream;
  2168. X{
  2169. X    putc('^', stream);
  2170. X    putc((c&31)|'@@', stream);
  2171. X}
  2172. X
  2173. X/*    doread.c    */
  2174. X/* #include <stdio.h> */
  2175. X/* #include "tools.h" */
  2176. X/* #include "ed.h" */
  2177. X
  2178. Xextern int diag;
  2179. X
  2180. Xdoread(lin, fname)
  2181. Xint    lin;
  2182. Xchar    *fname;
  2183. X{
  2184. X    extern FILE    *fopen();
  2185. X    FILE    *fp;
  2186. X    int    err;
  2187. X    long    bytes;
  2188. X    int    lines;
  2189. X    static char    str[MAXLINE];
  2190. X
  2191. X    err = 0;
  2192. X    nonascii = nullchar = truncated = 0;
  2193. X
  2194. X    if (diag) printf("\"%s\" ",fname);
  2195. X    if((fp = fopen(fname, "r")) == NULL)
  2196. X    {
  2197. X        printf("file open err\n");
  2198. X        return( ERR );
  2199. X    }
  2200. X    curln = lin;
  2201. X    for(lines = 0, bytes = 0;(err = egets(str,MAXLINE,fp)) > 0;)
  2202. X    {
  2203. X        bytes += strlen(str);
  2204. X        if(ins(str) < 0)
  2205. X        {
  2206. X            printf("file insert error\n");
  2207. X            err++;
  2208. X            break;
  2209. X        }
  2210. X        lines++;
  2211. X    }
  2212. X    fclose(fp);
  2213. X    if(err < 0)
  2214. X        return(err);
  2215. X    if (diag) {
  2216. X        printf("%d lines %d bytes",lines,bytes);
  2217. X        if(nonascii)
  2218. X            printf(" [%d non-ascii]",nonascii);
  2219. X        if(nullchar)
  2220. X            printf(" [%d nul]",nullchar);
  2221. X        if(truncated)
  2222. X            printf(" [%d lines truncated]",truncated);
  2223. X        printf("\n");
  2224. X    }
  2225. X    return( err );
  2226. X}
  2227. X
  2228. X/*    dowrite.c    */
  2229. X/* #include <stdio.h> */
  2230. X/* #include "tools.h" */
  2231. X/* #include "ed.h" */
  2232. X
  2233. Xdowrite(from, to, fname, apflg)
  2234. Xint    from, to;
  2235. Xchar    *fname;
  2236. Xint    apflg;
  2237. X{
  2238. X    extern FILE    *fopen();
  2239. X    FILE    *fp;
  2240. X    int    lin, err;
  2241. X    int    lines, bytes;
  2242. X    char    *str;
  2243. X
  2244. X    err = 0;
  2245. X
  2246. X    lines = bytes = 0;
  2247. X    if (diag)
  2248. X        printf("\"%s\" ",fname);
  2249. X    
  2250. X    if((fp = fopen(fname,(apflg?"a":"w"))) == NULL)
  2251. X    {
  2252. X        printf("file open error\n");
  2253. X        return( ERR );
  2254. X    }
  2255. X    for(lin = from; lin <= to; lin++)
  2256. X    {
  2257. X        str = gettxt(lin);
  2258. X        lines++;
  2259. X        bytes += strlen(str);
  2260. X        if(fputs(str, fp) == EOF)
  2261. X        {
  2262. X            printf("file write error\n");
  2263. X            err++;
  2264. X            break;
  2265. X        }
  2266. X    }
  2267. X    if (diag)
  2268. X        printf("%d lines %d bytes\n",lines,bytes);
  2269. X
  2270. X    fclose(fp);
  2271. X    return( err );
  2272. X}
  2273. X
  2274. X/*    ed.c    */
  2275. X/*
  2276. X * Copyright 1987 Brian Beattie Rights Reserved.
  2277. X *
  2278. X * Permission to copy and/or distribute granted under the
  2279. X * following conditions:
  2280. X *
  2281. X * 1). No charge may be made other than resonable charges
  2282. X *    for reproduction.
  2283. X *
  2284. X * 2). This notice must remain intact.
  2285. X *
  2286. X * 3). No further restrictions may be added.
  2287. X *
  2288. X */
  2289. X/* #include <stdio.h> */
  2290. X/* #include "tools.h" */
  2291. X/* #include "ed.h" */
  2292. X#include <setjmp.h>
  2293. Xjmp_buf    env;
  2294. X
  2295. XLINE    line0;
  2296. Xint    curln = 0;
  2297. Xint    lastln = 0;
  2298. Xchar    *inptr;
  2299. Xstatic char    inlin[MAXLINE];
  2300. Xint    nflg, lflg, pflg, pflag, prompt;
  2301. Xint    line1, line2, nlines;
  2302. Xextern char    fname[];
  2303. Xint    version = 103;
  2304. Xint    diag=1;
  2305. X
  2306. Xvoid intr()
  2307. X{
  2308. X    printf("?\n");
  2309. X    longjmp(env, 1);
  2310. X}
  2311. X
  2312. Xvoid main(argc,argv)
  2313. Xint    argc;
  2314. Xchar    **argv;
  2315. X{
  2316. X    int    stat, i, doflush;
  2317. X
  2318. X    edsetbuf();
  2319. X    doflush=isatty(1);
  2320. X
  2321. X    if (argc>1 && argv[1][0]=='-' && argv[1][1]==0) {
  2322. X        diag=0;
  2323. X        argc--;
  2324. X        argv++;
  2325. X    }
  2326. X    if(argc > 1)
  2327. X    {
  2328. X        for(i = 1; i < argc; i++)
  2329. X        {
  2330. X            if(doread(0,argv[i])==0) {
  2331. X                curln = 1;
  2332. X                strcpy(fname, argv[i]);
  2333. X                break;
  2334. X            }
  2335. X        }
  2336. X    }
  2337. X    while(1)
  2338. X    {
  2339. X        setjmp(env);
  2340. X        signal(2, intr);
  2341. X
  2342. X        if (prompt)
  2343. X        {
  2344. X            if (nflg) printf("%d",curln);
  2345. X            printf("*");
  2346. X        }
  2347. X
  2348. X        if (doflush) fflush(stdout);
  2349. X
  2350. X        if (fgets(inlin, sizeof(inlin),stdin) == NULL)
  2351. X        {
  2352. X            break;
  2353. X        }
  2354. X/*
  2355. X        if(*inlin == '!')
  2356. X        {
  2357. X            for(inptr = inlin; *inptr != NL; inptr++)
  2358. X                ;
  2359. X            *inptr = EOS;
  2360. X            system(inlin+1);
  2361. X            continue;
  2362. X        }
  2363. X*/
  2364. X        inptr = inlin;
  2365. X        if(getlst() >= 0)
  2366. X            if((stat = ckglob()) != 0)
  2367. X            {
  2368. X                if(stat >= 0 && (stat = doglob()) >= 0)
  2369. X                {
  2370. X                    curln = stat;
  2371. X                    continue;
  2372. X                }
  2373. X            } else {
  2374. X                if((stat = docmd(0)) >= 0)
  2375. X                {
  2376. X                    if(stat == 1)
  2377. X                        doprnt(curln, curln);
  2378. X                    continue;
  2379. X                }
  2380. X            }
  2381. X        if(stat == EOF)
  2382. X        {
  2383. X            exit(0);
  2384. X        }
  2385. X        if(stat == FATAL)
  2386. X        {
  2387. X            fputs("FATAL ERROR\n",stderr);
  2388. X            exit(1);
  2389. X        }
  2390. X        printf("?\n");
  2391. X    }
  2392. X}
  2393. X
  2394. X/*    egets.c    */
  2395. X/* #include <stdio.h> */
  2396. X/* #include "tools.h" */
  2397. X/* #include "ed.h" */
  2398. X
  2399. Xint    truncflg = 1;    /* truncate long line flag */
  2400. Xint    eightbit = 1;    /* save eight bit */
  2401. Xint    nonascii, nullchar, truncated;
  2402. Xegets(str,size,stream)
  2403. Xchar    *str;
  2404. Xint    size;
  2405. XFILE    *stream;
  2406. X{
  2407. X    int    c, count;
  2408. X    char    *cp;
  2409. X
  2410. X    for(count = 0, cp = str; size > count;)
  2411. X    {
  2412. X        c = getc(stream);
  2413. X        if(c == EOF)
  2414. X        {
  2415. X            *cp++ = '\n';
  2416. X            *cp = EOS;
  2417. X            if(count)
  2418. X            {
  2419. X                printf("[Incomplete last line]\n");
  2420. X            }
  2421. X            return(count);
  2422. X        }
  2423. X        if(c == NL)
  2424. X        {
  2425. X            *cp++ = c;
  2426. X            *cp = EOS;
  2427. X            return(++count);
  2428. X        }
  2429. X        if(c > 127)
  2430. X        {
  2431. X            if(!eightbit)        /* if not saving eighth bit */
  2432. X                c = c&127;    /* strip eigth bit */
  2433. X            nonascii++;        /* count it */
  2434. X        }
  2435. X        if(c)
  2436. X        {
  2437. X            *cp++ = c;    /* not null, keep it */
  2438. X            count++;
  2439. X        } else 
  2440. X            nullchar++;    /* count nulls */
  2441. X    }
  2442. X    str[count-1] = EOS;
  2443. X    if(c != NL)
  2444. X    {
  2445. X        printf("truncating line\n");
  2446. X        truncated++;
  2447. X        while((c = getc(stream)) != EOF)
  2448. X            if(c == NL)
  2449. X                break;
  2450. X    }
  2451. X    return(count);
  2452. X}
  2453. X
  2454. X/*    esc.c    */
  2455. X/* #include <stdio.h> */
  2456. X/* #include "tools.h" */
  2457. X
  2458. X/* Map escape sequences into their equivalent symbols.  Returns the
  2459. X * correct ASCII character.  If no escape prefix is present then s
  2460. X * is untouched and *s is returned, otherwise **s is advanced to point
  2461. X * at the escaped character and the translated character is returned.
  2462. X */
  2463. Xesc(s)
  2464. Xchar    **s;
  2465. X{
  2466. X    register int    rval;
  2467. X
  2468. X    
  2469. X    if (**s != ESCAPE)
  2470. X    {
  2471. X        rval = **s;
  2472. X    } else {
  2473. X        (*s)++;
  2474. X
  2475. X        switch(toupper(**s))
  2476. X        {
  2477. X        case '\000':
  2478. X            rval = ESCAPE;    break;
  2479. X        case 'S':
  2480. X            rval = ' ';    break;
  2481. X        case 'N':
  2482. X            rval = '\n';    break;
  2483. X        case 'T':
  2484. X            rval = '\t';    break;
  2485. X        case 'B':
  2486. X            rval = '\b';    break;
  2487. X        case 'R':
  2488. X            rval = '\r';    break;
  2489. X        default:
  2490. X            rval = **s;    break;
  2491. X        }
  2492. X    }
  2493. X
  2494. X    return (rval);
  2495. X}
  2496. X
  2497. X/*    find.c    */
  2498. X/* #include <stdio.h> */
  2499. X/* #include "tools.h" */
  2500. X/* #include "ed.h" */
  2501. X
  2502. Xfind(pat, dir)
  2503. XTOKEN    *pat;
  2504. Xint    dir;
  2505. X{
  2506. X    int    i, num;
  2507. X    char    *lin;
  2508. X
  2509. X    num=curln;
  2510. X    for(i=0; i<lastln; i++)
  2511. X    {
  2512. X        lin = gettxt(num);
  2513. X        if(matchs(lin, pat, 0))
  2514. X        {
  2515. X            return(num);
  2516. X        }
  2517. X        num = (dir ? nextln(num) : prevln(num));
  2518. X    }
  2519. X    return ( ERR );
  2520. X}
  2521. X
  2522. X/*    getfn.c    */
  2523. X/* #include <stdio.h> */
  2524. X/* #include "tools.h" */
  2525. X/* #include "ed.h" */
  2526. X
  2527. Xextern char    fname[MAXFNAME];
  2528. Xint nofname;
  2529. X
  2530. Xchar    *
  2531. Xgetfn()
  2532. X{
  2533. X    static char    file[256];
  2534. X    char    *cp;
  2535. X
  2536. X    if(*inptr == NL)
  2537. X    {
  2538. X        nofname=TRUE;
  2539. X        strcpy(file, fname);
  2540. X    } else {
  2541. X        nofname=FALSE;
  2542. X        while(*inptr == SP || *inptr == HT)
  2543. X            inptr++;
  2544. X
  2545. X        cp = file;
  2546. X        while(*inptr && *inptr != NL && *inptr != SP && *inptr != HT)
  2547. X        {
  2548. X            *cp++ = *inptr++;
  2549. X        }
  2550. X        *cp = '\0';
  2551. X
  2552. X        if(strlen(file) == 0)
  2553. X        {
  2554. X            printf("bad file name\n");
  2555. X            return( NULL );
  2556. X        }
  2557. X    }
  2558. X
  2559. X    if(strlen(file) == 0)
  2560. X    {
  2561. X        printf("no file name\n");
  2562. X        return(NULL);
  2563. X    }
  2564. X    return( file );
  2565. X}
  2566. X
  2567. X/*    getlst.c    */
  2568. X/* #include <stdio.h> */
  2569. X/* #include "tools.h" */
  2570. X/* #include "ed.h" */
  2571. X
  2572. Xgetlst()
  2573. X{
  2574. X    int    num;
  2575. X
  2576. X    line2 = 0;
  2577. X    for(nlines = 0; (num = getone()) >= 0;)
  2578. X    {
  2579. X        line1 = line2;
  2580. X        line2 = num;
  2581. X        nlines++;
  2582. X        if(*inptr != ',' && *inptr != ';')
  2583. X            break;
  2584. X        if(*inptr == ';')
  2585. X            curln = num;
  2586. X        inptr++;
  2587. X    }
  2588. X    nlines = min(nlines, 2);
  2589. X    if(nlines == 0)
  2590. X        line2 = curln;
  2591. X    if(nlines <= 1)
  2592. X        line1 = line2;
  2593. X
  2594. X    if(num == ERR)
  2595. X        return(num);
  2596. X    else
  2597. X        return(nlines);
  2598. X}
  2599. X
  2600. X/*    getnum.c    */
  2601. X/* #include <stdio.h> */
  2602. X/* #include "tools.h" */
  2603. X/* #include "ed.h" */
  2604. X
  2605. Xint mark['z'-'a'+1];
  2606. X
  2607. Xgetnum(first) int first;
  2608. X{
  2609. X    TOKEN    *srchpat;
  2610. X    int    num;
  2611. X    char    c;
  2612. X
  2613. X    while(*inptr == SP || *inptr == HT)
  2614. X        inptr++;
  2615. X
  2616. X    if(*inptr >= '0' && *inptr <= '9')    /* line number */
  2617. X    {
  2618. X        for(num = 0; *inptr >= '0' && *inptr <= '9';)
  2619. X        {
  2620. X            num = (num * 10) + *inptr - '0';
  2621. X            inptr++;
  2622. X        }
  2623. X        return num;
  2624. X    }
  2625. X
  2626. X    switch(c = *inptr)
  2627. X    {
  2628. X    case '.':
  2629. X        inptr++;
  2630. X        return (curln);
  2631. X
  2632. X    case '$':
  2633. X        inptr++;
  2634. X        return (lastln);
  2635. X
  2636. X    case '/':
  2637. X    case '?':
  2638. X        srchpat = optpat();
  2639. X        if(*inptr == c)
  2640. X            inptr++;
  2641. X        return(find(srchpat,c == '/'?1:0));
  2642. X
  2643. X    case '-':
  2644. X    case '+':
  2645. X        return(first ? curln : 1);
  2646. X
  2647. X    case '\'':
  2648. X        inptr++;
  2649. X        if (*inptr < 'a' || *inptr > 'z')
  2650. X            return(EOF);
  2651. X
  2652. X        return mark[ *inptr++ - 'a' ];
  2653. X
  2654. X    default:
  2655. X        return ( first ? EOF : 1 );    /* unknown address */
  2656. X    }
  2657. X}
  2658. X
  2659. X/*    getone.c    */
  2660. X/* #include <stdio.h> */
  2661. X/* #include "tools.h" */
  2662. X/* #include "ed.h" */
  2663. X
  2664. X#define FIRST 1
  2665. X#define NOTFIRST 0
  2666. X
  2667. Xgetone()
  2668. X{
  2669. X    int    c, i, num;
  2670. X
  2671. X    if((num = getnum(FIRST)) >= 0)
  2672. X    {
  2673. X        while(1)
  2674. X        {
  2675. X            while(*inptr == SP || *inptr == HT)
  2676. X                inptr++;
  2677. X
  2678. X            if(*inptr != '+' && *inptr != '-')
  2679. X                break;
  2680. X                        c = *inptr++;
  2681. X
  2682. X            if((i = getnum(NOTFIRST)) < 0)
  2683. X                return ( i );
  2684. X
  2685. X            if(c == '+')
  2686. X            {
  2687. X                num += i;
  2688. X            } else {
  2689. X                num -= i;
  2690. X            }
  2691. X        }
  2692. X    }
  2693. X    return ( num>lastln ? ERR : num );
  2694. X}
  2695. X
  2696. X/*    getpat.c    */
  2697. X/* #include <stdio.h> */
  2698. X/* #include "tools.h" */
  2699. X
  2700. X/* Translate arg into a TOKEN string */
  2701. XTOKEN    *
  2702. Xgetpat (arg)
  2703. Xchar    *arg;
  2704. X{
  2705. X    
  2706. X    return (makepat(arg, '\000'));
  2707. X}
  2708. X
  2709. X/*    getptr.c    */
  2710. X/* #include <stdio.h> */
  2711. X/* #include "tools.h" */
  2712. X/* #include "ed.h" */
  2713. X
  2714. XLINE    *
  2715. Xgetptr(num)
  2716. Xint    num;
  2717. X{
  2718. X    LINE    *ptr;
  2719. X    int    j;
  2720. X
  2721. X    if (2*num>lastln && num<=lastln) {    /* high line numbers */
  2722. X        ptr = line0.l_prev;
  2723. X        for (j = lastln; j>num; j--)
  2724. X            ptr = ptr->l_prev;
  2725. X    } else {                /* low line numbers */
  2726. X        ptr = &line0;
  2727. X        for(j = 0; j < num; j++)
  2728. X            ptr = ptr->l_next;
  2729. X    }
  2730. X    return(ptr);
  2731. X}
  2732. X
  2733. X/*    getrhs.c    */
  2734. X/* #include <stdio.h> */
  2735. X/* #include "tools.h" */
  2736. X/* #include "ed.h" */
  2737. X
  2738. Xgetrhs(sub)
  2739. Xchar    *sub;
  2740. X{
  2741. X    if(inptr[0] == NL || inptr[1] == NL)    /* check for eol */
  2742. X        return( ERR );
  2743. X
  2744. X    if(maksub(sub, MAXPAT) == NULL)
  2745. X        return( ERR );
  2746. X    
  2747. X    inptr++;        /* skip over delimter */
  2748. X    while(*inptr == SP || *inptr == HT)
  2749. X            inptr++;
  2750. X    if(*inptr == 'g')
  2751. X    {
  2752. X        inptr++;
  2753. X        return( 1 );
  2754. X    }
  2755. X    return( 0 );
  2756. X}
  2757. X
  2758. X/*    gettxt.c    */
  2759. X/* #include <stdio.h> */
  2760. X/* #include "tools.h" */
  2761. X/* #include "ed.h" */
  2762. X
  2763. Xchar    *
  2764. Xgettxt(num)
  2765. Xint    num;
  2766. X{
  2767. X    LINE    *lin;
  2768. X    static char    txtbuf[MAXLINE];
  2769. X
  2770. X    lin = getptr(num);
  2771. X    strcpy(txtbuf,lin->l_buff);
  2772. X    strcat(txtbuf,"\n");
  2773. X    return(txtbuf);
  2774. X}
  2775. X
  2776. X/*    ins.c    */
  2777. X/* #include <stdio.h> */
  2778. X/* #include "tools.h" */
  2779. X/* #include "ed.h" */
  2780. X
  2781. Xins(str)
  2782. Xchar    *str;
  2783. X{
  2784. X    char    buf[MAXLINE], *cp;
  2785. X    LINE    *new, *cur, *nxt;
  2786. X
  2787. X    cp = buf;
  2788. X    while(1)
  2789. X    {
  2790. X        if((*cp = *str++) == NL)
  2791. X            *cp = EOS;
  2792. X        if(*cp)
  2793. X        {
  2794. X            cp++;
  2795. X            continue;
  2796. X        }
  2797. X        if((new = (LINE *)malloc(sizeof(LINE)+strlen(buf))) == NULL)
  2798. X            return( ERR );     /* no memory */
  2799. X
  2800. X        new->l_stat=0;
  2801. X        strcpy(new->l_buff,buf);    /* build new line */
  2802. X        cur = getptr(curln);        /* get current line */
  2803. X        nxt = getptr(nextln(curln));    /* get next line */
  2804. X        relink(cur, new, new, nxt);    /* add to linked list */
  2805. X        relink(new, nxt, cur, new);
  2806. X        lastln++;
  2807. X        curln++;
  2808. X
  2809. X        if(*str == EOS)        /* end of line ? */
  2810. X            return( 1 );
  2811. X
  2812. X        cp = buf;
  2813. X    }
  2814. X}
  2815. X
  2816. X/*    join.c    */
  2817. X/* #include <stdio.h> */
  2818. X/* #include "tools.h" */
  2819. X/* #include "ed.h" */
  2820. X
  2821. Xextern int fchanged;
  2822. X
  2823. Xjoin(first, last)
  2824. Xint first, last;
  2825. X{
  2826. X    char buf[MAXLINE];
  2827. X    char *cp=buf, *str;
  2828. X    int num;
  2829. X
  2830. X    if (first<=0 || first>last || last>lastln)
  2831. X        return(ERR);
  2832. X    if (first==last) {
  2833. X        curln=first;
  2834. X        return 0;
  2835. X    }
  2836. X    for (num=first; num<=last; num++) {
  2837. X        str=gettxt(num);
  2838. X
  2839. X        while (*str!=NL && cp<buf+MAXLINE-1) *cp++ = *str++;
  2840. X
  2841. X        if (cp==buf+MAXLINE-1) {
  2842. X            printf("line too long\n");
  2843. X            return(ERR);
  2844. X        }
  2845. X    }
  2846. X    *cp++ = NL;
  2847. X    *cp = EOS;
  2848. X    del(first, last);
  2849. X    curln=first-1;
  2850. X    ins(buf);
  2851. X    fchanged = TRUE;
  2852. X    return 0;
  2853. X}
  2854. X
  2855. X/*    makepat.c    */
  2856. X/* #include <stdio.h> */
  2857. X/* #include "tools.h" */
  2858. X
  2859. X/*
  2860. X * Make a pattern template from the strinng pointed to by arg.  Stop
  2861. X * when delim or '\000' or '\n' is found in arg.  Return a pointer to
  2862. X * the pattern template.
  2863. X *
  2864. X * The pattern template used here are somewhat different than those
  2865. X * used in the "Software Tools" book; each token is a structure of
  2866. X * the form TOKEN (see tools.h).  A token consists of an identifier,
  2867. X * a pointer to a string, a literal character and a pointer to another
  2868. X * token.  This last is 0 if there is no subsequent token.
  2869. X *
  2870. X * The one strangeness here is caused (again) by CLOSURE which has
  2871. X * to be put in front of the previous token.  To make this insertion a
  2872. X * little easier, the 'next' field of the last to point at the chain
  2873. X * (the one pointed to by 'tail) is made to point at the previous node.
  2874. X * When we are finished, tail->next is set to 0.
  2875. X */
  2876. XTOKEN *
  2877. Xmakepat(arg, delim)
  2878. Xchar    *arg;
  2879. Xint    delim;
  2880. X{
  2881. X     TOKEN    *head, *tail, *ntok;
  2882. X     int    error;
  2883. X
  2884. X    /*
  2885. X     * Check for characters that aren't legal at the beginning of
  2886. X     * a template.
  2887. X     */
  2888. X
  2889. X    if (*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE)
  2890. X        return(0);
  2891. X
  2892. X    error = 0;
  2893. X    tail = head = NULL;
  2894. X
  2895. X    while (*arg && *arg != delim && *arg != '\n' && !error)
  2896. X    {
  2897. X        ntok = (TOKEN *)malloc(TOKSIZE);
  2898. X        ntok->lchar = '\000';
  2899. X        ntok->next = 0;
  2900. X
  2901. X        switch(*arg)
  2902. X        {
  2903. X        case ANY:
  2904. X            ntok->tok = ANY;
  2905. X            break;
  2906. X
  2907. X        case BOL:
  2908. X            if (head == 0)    /* then this is the first symbol */
  2909. X                ntok->tok = BOL;
  2910. X            else
  2911. X                ntok->tok = LITCHAR;
  2912. X                ntok->lchar = BOL;
  2913. X            break;
  2914. X
  2915. X        case EOL:
  2916. X            if(*(arg+1) == delim || *(arg+1) == '\000' ||
  2917. X                    *(arg+1) == '\n')
  2918. X            {
  2919. X                ntok->tok = EOL;
  2920. X            } else {
  2921. X                ntok->tok = LITCHAR;
  2922. X                ntok->lchar = EOL;
  2923. X            }
  2924. X            break;
  2925. X
  2926. X        case CLOSURE:
  2927. X            if (head != 0)
  2928. X            {
  2929. X                switch (tail->tok)
  2930. X                {
  2931. X                case BOL:
  2932. X                case EOL:
  2933. X                case CLOSURE:
  2934. X                    return (0);
  2935. X                
  2936. X                default:
  2937. X                    ntok->tok = CLOSURE;
  2938. X                }
  2939. X            }
  2940. X            break;
  2941. X
  2942. X        case CCL:
  2943. X
  2944. X            if(*(arg + 1) == NEGATE)
  2945. X            {
  2946. X                ntok->tok = NCCL;
  2947. X                arg += 2;
  2948. X            } else {
  2949. X                ntok->tok = CCL;
  2950. X                arg++;
  2951. X            }
  2952. X
  2953. X            if( ntok->bitmap = makebitmap(CLS_SIZE) )
  2954. X                arg = dodash(CCLEND, arg, ntok->bitmap );
  2955. X            else {
  2956. X                fprintf(stderr,"Not enough memory for pat\n");
  2957. X                error = 1;
  2958. X            }
  2959. X            break;
  2960. X
  2961. X        default:
  2962. X            if (*arg == ESCAPE && *(arg+1) == OPEN) {
  2963. X                ntok->tok = OPEN;
  2964. X                arg++;
  2965. X            } else
  2966. X            if (*arg == ESCAPE && *(arg+1) == CLOSE) {
  2967. X                ntok->tok = CLOSE;
  2968. X                arg++;
  2969. X            } else {
  2970. X                ntok->tok = LITCHAR;
  2971. X                ntok->lchar = esc(&arg);
  2972. X            }
  2973. X        }
  2974. X
  2975. X        if (error || ntok == 0)
  2976. X        {
  2977. X            unmakepat(head);
  2978. X            return (0);
  2979. X        } else if (head == 0)
  2980. X        {
  2981. X                /* This is the first node in the chain. */
  2982. X            
  2983. X            ntok->next = 0;
  2984. X            head = tail = ntok;
  2985. X        } else if (ntok->tok != CLOSURE)
  2986. X        {
  2987. X            /* Insert at end of list (after tail) */
  2988. X
  2989. X            tail->next = ntok;
  2990. X            ntok->next = tail;
  2991. X            tail = ntok;
  2992. X        } else if (head != tail)
  2993. X        {
  2994. X            /*
  2995. X             * More than one node in the chain.  Insert the
  2996. X             * CLOSURE node immediately in front of tail.
  2997. X             */
  2998. X            
  2999. X            (tail->next)->next = ntok;
  3000. X            ntok->next = tail;
  3001. X        } else {
  3002. X            /*
  3003. X             * Only one node in the chain,  Insert the CLOSURE
  3004. X             * node at the head of the linked list.
  3005. X             */
  3006. X            
  3007. X            ntok->next = head;
  3008. X            tail->next = ntok;
  3009. X            head = ntok;
  3010. X        }
  3011. X        arg++;
  3012. X    }
  3013. X
  3014. X    tail->next = 0;
  3015. X    return (head);
  3016. X}
  3017. X
  3018. X/*    maksub.c    */
  3019. X/* #include <stdio.h> */
  3020. X/* #include "tools.h" */
  3021. X/* #include "ed.h" */
  3022. X
  3023. Xchar    *
  3024. Xmaksub(sub, subsz)
  3025. Xchar    *sub;
  3026. Xint    subsz;
  3027. X{
  3028. X    int    size;
  3029. X    char    delim, *cp;
  3030. X
  3031. X    size = 0;
  3032. X    cp = sub;
  3033. X
  3034. X    delim = *inptr++;
  3035. X    for(size = 0; *inptr != delim && *inptr != NL && size < subsz; size++)
  3036. X    {
  3037. X        if(*inptr == '&')
  3038. X        {
  3039. X            *cp++ = DITTO;
  3040. X            inptr++;
  3041. X        } else
  3042. X        if((*cp++ = *inptr++) == ESCAPE)
  3043. X        {
  3044. X            if (size>=subsz) return(NULL);
  3045. X
  3046. X            switch(toupper(*inptr))
  3047. X            {
  3048. X            case NL:
  3049. X                *cp++ = ESCAPE;
  3050. X                break;
  3051. X            case 'S':
  3052. X                *cp++ = SP;
  3053. X                inptr++;
  3054. X                break;
  3055. X            case 'N':
  3056. X                *cp++ = NL;
  3057. X                inptr++;
  3058. X                break;
  3059. X            case 'T':
  3060. X                *cp++ = HT;
  3061. X                inptr++;
  3062. X                break;
  3063. X            case 'B':
  3064. X                *cp++ = BS;
  3065. X                inptr++;
  3066. X                break;
  3067. X            case 'R':
  3068. X                *cp++ = CR;
  3069. X                inptr++;
  3070. X                break;
  3071. X            case '0': {
  3072. X                int i=3;
  3073. X                *cp = 0;
  3074. X                do {
  3075. X                    if (*++inptr<'0' || *inptr >'7')
  3076. X                        break;
  3077. X
  3078. X                    *cp = (*cp<<3) | (*inptr-'0');
  3079. X                } while (--i!=0);
  3080. X                cp++;
  3081. X                } break;
  3082. X            default:
  3083. X                *cp++ = *inptr++;
  3084. X                break;
  3085. X            }
  3086. X        }
  3087. X    }
  3088. X    if(size >= subsz)
  3089. X        return( NULL );
  3090. X
  3091. X    *cp = EOS;
  3092. X    return( sub );
  3093. X}
  3094. X
  3095. X/*    matchs.c    */
  3096. X/* #include <stdio.h> */
  3097. X/* #include "tools.h" */
  3098. X
  3099. X/*
  3100. X * Compares line and pattern.  Line is a character string while pat
  3101. X * is a pattern template made by getpat().
  3102. X * Returns:
  3103. X *    1. A zero if no match was found.
  3104. X *
  3105. X *    2. A pointer to the last character satisfing the match
  3106. X *       if ret_endp is non-zero.
  3107. X *
  3108. X *    3. A pointer to the beginning of the matched string if
  3109. X *       ret_endp is zero.
  3110. X *
  3111. X * e.g.:
  3112. X *
  3113. X *    matchs ("1234567890", getpat("4[0-9]*7), 0);
  3114. X * will return a pointer to the '4', while:
  3115. X *
  3116. X *    matchs ("1234567890", getpat("4[0-9]*7), 1);
  3117. X * will return a pointer to the '7'.
  3118. X */
  3119. Xchar    *
  3120. Xmatchs(line, pat, ret_endp)
  3121. Xchar    *line;
  3122. XTOKEN    *pat;
  3123. Xint    ret_endp;
  3124. X{
  3125. X
  3126. X    char    *rval, *bptr;
  3127. X
  3128. X    bptr = line;
  3129. X
  3130. X    while(*line)
  3131. X    {
  3132. X        if ((rval = amatch(line, pat, bptr)) == 0)
  3133. X        {
  3134. X            line++;
  3135. X        } else {
  3136. X            if(rval > bptr && rval > line)
  3137. X                rval--;    /* point to last char matched */
  3138. X            rval = ret_endp ? rval : line;
  3139. X            break;
  3140. X        }
  3141. X    }
  3142. X    return (rval);
  3143. X}
  3144. X
  3145. X/*    move.c    */
  3146. X/* #include <stdio.h> */
  3147. X/* #include "tools.h" */
  3148. X/* #include "ed.h" */
  3149. X
  3150. Xmove(num)
  3151. Xint    num;
  3152. X{
  3153. X    LINE    *k0, *k1, *k2, *k3;
  3154. X
  3155. X    if(line1 <= 0 || line2 < line1 || line1 <= num && num <= line2)
  3156. X        return( ERR );
  3157. X    k0 = getptr(prevln(line1));
  3158. X    k1 = getptr(line1);
  3159. X    k2 = getptr(line2);
  3160. X    k3 = getptr(nextln(line2));
  3161. X     lastln -= line2-line1+1;
  3162. X
  3163. X    relink(k0, k3, k0, k3);
  3164. X
  3165. X    if (num > line1)
  3166. X        num -= line2-line1+1;
  3167. X
  3168. X    curln = num + (line2 - line1 + 1);
  3169. X
  3170. X    k0 = getptr(num);
  3171. X    k3 = getptr(nextln(num));
  3172. X     lastln += line2-line1+1;
  3173. X
  3174. X    relink(k0, k1, k2, k3);
  3175. X    relink(k2, k3, k0, k1);
  3176. X
  3177. X    return( 1 );
  3178. X}
  3179. X
  3180. Xint transfer(num)
  3181. Xint num;
  3182. X{
  3183. X    int mid, lin, ntrans;
  3184. X
  3185. X    if (line1<=0 || line1>line2)
  3186. X        return(ERR);
  3187. X
  3188. X    mid= num<line2 ? num : line2;
  3189. X
  3190. X    curln=num;
  3191. X    ntrans=0;
  3192. X
  3193. X    for (lin=line1; lin<=mid; lin++) {
  3194. X        ins(gettxt(lin));
  3195. X        ntrans++;
  3196. X    }
  3197. X    lin+=ntrans;
  3198. X    line2+=ntrans;
  3199. X
  3200. X    for ( ; lin<=line2; lin+=2) {
  3201. X        ins(gettxt(lin));
  3202. X        line2++;
  3203. X    }
  3204. X    return(1);
  3205. X}
  3206. X
  3207. X/*    omatch.c    */
  3208. X/* #include <stdio.h> */
  3209. X/* #include "tools.h" */
  3210. X
  3211. X/*
  3212. X * Match one pattern element, pointed at by pat, with the character at
  3213. X * **linp.  Return non-zero on match.  Otherwise, return 0.  *Linp is
  3214. X * advanced to skip over the matched character; it is not advanced on
  3215. X * failure.  The amount of advance is 0 for patterns that match null
  3216. X * strings, 1 otherwise.  "boln" should point at the position that will
  3217. X * match a BOL token.
  3218. X */
  3219. Xomatch(linp, pat, boln)
  3220. Xchar    **linp;
  3221. XTOKEN    *pat;
  3222. Xchar    *boln;
  3223. X{
  3224. X    
  3225. X    register int    advance;
  3226. X
  3227. X    advance = -1;
  3228. X
  3229. X    if (**linp)
  3230. X    {
  3231. X        switch (pat->tok)
  3232. X        {
  3233. X        case LITCHAR:
  3234. X            if (**linp == pat->lchar)
  3235. X                advance = 1;
  3236. X            break;
  3237. X
  3238. X        case BOL:
  3239. X            if (*linp = boln)
  3240. X                advance = 0;
  3241. X            break;
  3242. X
  3243. X        case ANY:
  3244. X            if (**linp != '\n')
  3245. X                advance = 1;
  3246. X            break;
  3247. X
  3248. X        case EOL:
  3249. X            if (**linp == '\n')
  3250. X                advance = 0;
  3251. X            break;
  3252. X
  3253. X        case CCL:
  3254. X            if( testbit( **linp, pat->bitmap))
  3255. X                advance = 1;
  3256. X            break;
  3257. X
  3258. X        case NCCL:
  3259. X            if (!testbit (**linp, pat->bitmap))
  3260. X                advance = 1;
  3261. X            break;
  3262. X        }
  3263. X    }
  3264. X    if (advance >= 0)
  3265. X        *linp += advance;
  3266. X
  3267. X    return (++advance);
  3268. X}
  3269. X
  3270. X/*    optpat.c    */
  3271. X/* #include <stdio.h> */
  3272. X/* #include "tools.h" */
  3273. X/* #include "ed.h" */
  3274. X
  3275. XTOKEN    *oldpat;
  3276. X
  3277. XTOKEN    *
  3278. Xoptpat()
  3279. X{
  3280. X    char    delim, str[MAXPAT], *cp;
  3281. X
  3282. X    delim = *inptr++;
  3283. X    cp = str;
  3284. X    while(*inptr != delim && *inptr != NL)
  3285. X    {
  3286. X        if(*inptr == ESCAPE && inptr[1] != NL)
  3287. X            *cp++ = *inptr++;
  3288. X        *cp++ = *inptr++;
  3289. X    }
  3290. X
  3291. X    *cp = EOS;
  3292. X    if(*str == EOS)
  3293. X        return(oldpat);
  3294. X    if(oldpat)
  3295. X        unmakepat(oldpat);
  3296. X    oldpat=getpat(str);
  3297. X    return(oldpat);
  3298. X}
  3299. X
  3300. X/*    set.c    */
  3301. X/* #include <stdio.h> */
  3302. X/* #include "tools.h" */
  3303. X/* #include "ed.h" */
  3304. X
  3305. Xstruct tbl {
  3306. X    char    *t_str;
  3307. X    int    *t_ptr;
  3308. X    int    t_val;
  3309. X} *t, tbl[] = {
  3310. X    "number",    &nflg,        TRUE,
  3311. X    "nonumber",    &nflg,        FALSE,
  3312. X    "list",        &lflg,        TRUE,
  3313. X    "nolist",    &lflg,        FALSE,
  3314. X    "eightbit",    &eightbit,    TRUE,
  3315. X    "noeightbit",    &eightbit,    FALSE,
  3316. X    "prompt",    &prompt,    TRUE,
  3317. X    "noprompt",    &prompt,    FALSE,
  3318. X    0
  3319. X};
  3320. X
  3321. Xset()
  3322. X{
  3323. X    char    word[16];
  3324. X    int    i;
  3325. X
  3326. X    inptr++;
  3327. X    if(*inptr != 't')
  3328. X    {
  3329. X        if(*inptr != SP && *inptr != HT && *inptr != NL)
  3330. X            return(ERR);
  3331. X    } else
  3332. X        inptr++;
  3333. X
  3334. X    if(*inptr == NL)
  3335. X        return(show("all"));
  3336. X        /* skip white space */
  3337. X    while(*inptr == SP || *inptr == HT)
  3338. X        inptr++;
  3339. X
  3340. X    for(i = 0; *inptr != SP && *inptr != HT && *inptr != NL;)
  3341. X        word[i++] = *inptr++;
  3342. X    word[i] = EOS;
  3343. X    for(t = tbl; t->t_str; t++)
  3344. X    {
  3345. X        if(strcmp(word,t->t_str) == 0)
  3346. X        {
  3347. X            *t->t_ptr = t->t_val;
  3348. X            return(0);
  3349. X        }
  3350. X    }
  3351. X}
  3352. X
  3353. Xshow()
  3354. X{
  3355. X    extern int    version;
  3356. X
  3357. X    printf("ed version %d.%d\n",version/100,version%100);
  3358. X    printf("number %s, ",nflg?"ON":"OFF");
  3359. X    printf("list %s, ",lflg?"ON":"OFF");
  3360. X    printf("prompt %s,\n",prompt?"ON":"OFF");
  3361. X    return(0);
  3362. X}
  3363. X
  3364. X/*    setbuf.c    */
  3365. X/* #include <stdio.h> */
  3366. X/* #include "tools.h" */
  3367. X/* #include "ed.h" */
  3368. X
  3369. Xvoid relink(a, x, y, b)
  3370. XLINE    *a, *x, *y, *b;
  3371. X{
  3372. X    x->l_prev = a;
  3373. X    y->l_next = b;
  3374. X}
  3375. X
  3376. Xvoid clrbuf()
  3377. X{
  3378. X    del(1, lastln);
  3379. X}
  3380. X
  3381. Xvoid edsetbuf()
  3382. X{
  3383. X    relink(&line0, &line0, &line0, &line0);
  3384. X    curln = lastln = 0;
  3385. X}
  3386. X
  3387. X/*    subst.c    */
  3388. X/* #include <stdio.h> */
  3389. X/* #include "tools.h" */
  3390. X/* #include "ed.h" */
  3391. X
  3392. Xsubst(pat, sub, gflg, pflag)
  3393. XTOKEN    *pat;
  3394. Xchar    *sub;
  3395. Xint    gflg, pflag;
  3396. X{
  3397. X    int    lin, chngd, nchngd;
  3398. X    char    *txtptr, *txt;
  3399. X    char    *lastm, *m, *new, buf[MAXLINE];
  3400. X
  3401. X    if(line1 <= 0)
  3402. X        return( ERR );
  3403. X    nchngd = 0;        /* reset count of lines changed */
  3404. X    for(lin = line1; lin <= line2; lin++)
  3405. X    {
  3406. X        txt = txtptr = gettxt(lin);
  3407. X        new = buf;
  3408. X        chngd = 0;
  3409. X        lastm = NULL;
  3410. X        while(*txtptr)
  3411. X        {
  3412. X            if(gflg || !chngd)
  3413. X                m = amatch(txtptr, pat, txt);
  3414. X            else
  3415. X                m = NULL;
  3416. X            if(m != NULL && lastm != m)
  3417. X            {
  3418. X                chngd++;
  3419. X                new = catsub(txtptr, m, sub, new,
  3420. X                        buf+MAXLINE);
  3421. X                lastm = m;
  3422. X            }
  3423. X            if(m == NULL || m == txtptr)
  3424. X            {
  3425. X                *new++ = *txtptr++;
  3426. X            } else {
  3427. X                txtptr = m;
  3428. X            }
  3429. X        }
  3430. X        if(chngd)
  3431. X        {
  3432. X            if(new >= buf+MAXLINE)
  3433. X                return( ERR );
  3434. X            *new++ = EOS;
  3435. X            del(lin,lin);
  3436. X            ins(buf);
  3437. X            nchngd++;
  3438. X            if(pflag)
  3439. X                doprnt(curln, curln);
  3440. X        }
  3441. X    }
  3442. X    if(nchngd == 0 && !gflg)
  3443. X    {
  3444. X        return(ERR);
  3445. X    }
  3446. X    return( nchngd );
  3447. X}
  3448. X
  3449. X#if 0
  3450. X/*    system.c    */
  3451. X#define SHELL    "/bin/sh"
  3452. X
  3453. Xsystem(c)
  3454. Xchar *c; {
  3455. X    int pid, status;
  3456. X    
  3457. X    switch (pid = fork()) {
  3458. X    case -1:
  3459. X        return -1;
  3460. X    case 0:
  3461. X        execl(SHELL, "sh", "-c", c, (char *) 0);
  3462. X        exit(-1);
  3463. X    default:
  3464. X        while (wait(&status) != pid)
  3465. X            ;
  3466. X    }
  3467. X    return status;
  3468. X}
  3469. X#endif
  3470. X
  3471. X/*    unmkpat.c    */
  3472. X/* #include <stdio.h> */
  3473. X/* #include "tools.h" */
  3474. X
  3475. X/* Free up the memory usde for token string */
  3476. Xvoid unmakepat(head)
  3477. XTOKEN    *head;
  3478. X{
  3479. X
  3480. X    register TOKEN    *old_head;
  3481. X
  3482. X    while (head)
  3483. X    {
  3484. X        switch (head->tok)
  3485. X        {
  3486. X        case CCL:
  3487. X        case NCCL:
  3488. X            free(head->bitmap);
  3489. X                /* fall through to default */
  3490. X
  3491. X        default:
  3492. X            old_head = head;
  3493. X            head = head->next;
  3494. X            free (old_head);
  3495. X            break;
  3496. X        }
  3497. X    }
  3498. X}
  3499. X
  3500. Xisatty(fd)
  3501. Xint        fd;
  3502. X{
  3503. X    long IsInteractive();
  3504. X    struct UFB    *ufb;
  3505. X
  3506. X    ufb = chkufb(fd);
  3507. X    if (ufb == NULL)
  3508. X        return(-1);
  3509. X    return(IsInteractive(ufb->ufbfh) != 0);
  3510. X}
  3511. X@
  3512. X
  3513. X
  3514. X1.4
  3515. Xlog
  3516. X@More amiga changes
  3517. X@
  3518. Xtext
  3519. X@d3 2
  3520. Xd36 1
  3521. Xd41 1
  3522. Xa41 1
  3523. X"$Header: Rodime:ricks/ked2/ked2.c,v 1.3 89/09/01 11:02:22 rick Exp Locker: rick $";
  3524. Xd144 1
  3525. Xa144 1
  3526. Xextern    int    unmakepat();
  3527. Xa153 2
  3528. X#define max(a,b)    ((a>b)?a:b)
  3529. X#define min(a,b)    ((a<b)?a:b)
  3530. Xd201 1
  3531. Xa229 1
  3532. X    register i;
  3533. Xd594 1
  3534. Xd614 1
  3535. Xa614 1
  3536. X    int    i, apflg, pflag, gflag;
  3537. Xd1056 1
  3538. Xa1056 1
  3539. Xprntln(str, vflg, lin)
  3540. Xd1093 1
  3541. Xa1093 1
  3542. Xputcntl(c, stream)
  3543. Xd1234 1
  3544. Xa1234 1
  3545. Xintr()
  3546. Xd1240 1
  3547. Xa1240 1
  3548. Xmain(argc,argv)
  3549. Xd1244 1
  3550. Xa1244 1
  3551. X    int    stat, i, j, doflush;
  3552. Xd1246 1
  3553. Xa1246 1
  3554. X    setbuf();
  3555. Xa1809 1
  3556. X     char    buf[CLS_SIZE];
  3557. Xd2297 1
  3558. Xa2297 1
  3559. Xrelink(a, x, y, b)
  3560. Xd2304 1
  3561. Xa2304 1
  3562. Xclrbuf()
  3563. Xd2309 1
  3564. Xa2309 1
  3565. Xint setbuf()
  3566. Xd2404 1
  3567. Xa2404 1
  3568. Xunmakepat(head)
  3569. Xd2428 5
  3570. Xd2434 5
  3571. X@
  3572. X
  3573. X
  3574. X1.3
  3575. Xlog
  3576. X@Amiga changes
  3577. X@
  3578. Xtext
  3579. X@d38 1
  3580. Xa38 1
  3581. X"$Header: Quantum:ricks/ked2/ed.c,v 1.1 89/08/27 17:44:11 rick Exp Locker: rick $";
  3582. Xd1309 1
  3583. Xa1309 1
  3584. X            _cleanup(); exit(0);
  3585. Xd1314 1
  3586. Xa1314 1
  3587. X            _cleanup(); exit(1);
  3588. X@
  3589. X
  3590. X
  3591. X1.2
  3592. Xlog
  3593. X@No changes
  3594. X@
  3595. Xtext
  3596. X@d1280 1
  3597. Xd1289 1
  3598. Xd2308 1
  3599. Xa2308 1
  3600. Xvoid setbuf()
  3601. Xd2376 1
  3602. Xd2396 1
  3603. X@
  3604. X
  3605. X
  3606. X1.1
  3607. Xlog
  3608. X@Initial revision
  3609. X@
  3610. Xtext
  3611. X@d38 1
  3612. Xa38 1
  3613. X"$Header: ed.c,v 1.6 88/05/23 16:47:56 dnix Exp $";
  3614. X@
  3615. SHAR_EOF
  3616. if `test ! -d rcs`
  3617. then
  3618.   mkdir rcs
  3619.   echo "mkdir rcs"
  3620. fi
  3621. echo "extracting rcs/readme"
  3622. sed 's/^X//' << \SHAR_EOF > rcs/readme
  3623. XThe source code for RCS is distrubuted as RCSfiles. This is so that you will
  3624. Xhave the original sources and the current Amiga sources (and intermediate
  3625. Xversions). It also provides a collection of RCSfiles that newcommers to RCS
  3626. Xcan play with to learn what RCS does.
  3627. X
  3628. X
  3629. X                    Ray
  3630. SHAR_EOF
  3631. if `test ! -d rcs/rcs.rcsfiles`
  3632. then
  3633.   mkdir rcs/rcs.rcsfiles
  3634.   echo "mkdir rcs/rcs.rcsfiles"
  3635. fi
  3636. echo "extracting rcs/rcs.rcsfiles/maketime.c,v"
  3637. sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/maketime.c,v
  3638. Xhead     1.8;
  3639. Xbranch   1.8.2;
  3640. Xaccess   ;
  3641. Xsymbols  amiga_rcs:1.8.2 cbmvax_source:1.8.1 uunet_june89_dist:1.8;
  3642. Xlocks    ; strict;
  3643. Xcomment  @ * @;
  3644. X
  3645. X
  3646. X1.8
  3647. Xdate     88.11.08.13.54.53;  author narten;  state Exp;
  3648. Xbranches 1.8.1.1 1.8.2.1;
  3649. Xnext     ;
  3650. X
  3651. X1.8.1.1
  3652. Xdate     89.08.11.01.41.52;  author rsbx;  state Exp;
  3653. Xbranches ;
  3654. Xnext     ;
  3655. X
  3656. X1.8.2.1
  3657. Xdate     89.10.13.19.17.37;  author rsbx;  state Exp;
  3658. Xbranches ;
  3659. Xnext     1.8.2.2;
  3660. X
  3661. X1.8.2.2
  3662. Xdate     89.10.15.15.43.22;  author rsbx;  state Exp;
  3663. Xbranches ;
  3664. Xnext     ;
  3665. X
  3666. X
  3667. Xdesc
  3668. X@derive 32-bit time value from TM structure.
  3669. X@
  3670. X
  3671. X
  3672. X
  3673. X1.8
  3674. Xlog
  3675. X@checked in with -k by rsbx at 89.08.10.16.02.32.
  3676. X@
  3677. Xtext
  3678. X@#
  3679. X/*
  3680. X * MAKETIME        derive 32-bit time value from TM structure.
  3681. X *
  3682. X * Usage:
  3683. X *    long t,maketime();
  3684. X *    struct tm *tp;    Pointer to TM structure from <time.h>
  3685. X *            NOTE: this must be extended version!!!
  3686. X *    t = maketime(tp);
  3687. X *
  3688. X * Returns:
  3689. X *    0 if failure; parameter out of range or nonsensical.
  3690. X *    else long time-value.
  3691. X * Notes:
  3692. X *    This code is quasi-public; it may be used freely in like software.
  3693. X *    It is not to be sold, nor used in licensed software without
  3694. X *    permission of the author.
  3695. X *    For everyone's benefit, please report bugs and improvements!
  3696. X *     Copyright 1981 by Ken Harrenstien, SRI International.
  3697. X *    (ARPANET: KLH @@ SRI)
  3698. X */
  3699. X#ifndef lint
  3700. Xstatic char rcsid[]= "$Id: maketime.c,v 1.8 88/11/08 13:54:53 narten Exp $";
  3701. X#endif
  3702. X/* $Log:    maketime.c,v $
  3703. X * Revision 1.8  88/11/08  13:54:53  narten
  3704. X * allow negative timezones (-24h <= x <= 24h)
  3705. X * 
  3706. X * Revision 1.7  88/11/08  12:02:24  narten
  3707. X * changes from  eggert@@sm.unisys.com (Paul Eggert)
  3708. X * 
  3709. X * Revision 1.7  88/08/28  14:47:52  eggert
  3710. X * Allow cc -R.  Remove unportable "#endif XXX"s.
  3711. X * 
  3712. X * Revision 1.6  87/12/18  17:05:58  narten
  3713. X * include rcsparam.h
  3714. X * 
  3715. X * Revision 1.5  87/12/18  11:35:51  narten
  3716. X * maketime.c: fixed USG code - you have tgo call "tzset" in order to have
  3717. X * "timezone" set. ("localtime" calls it, but it's probably better not to 
  3718. X * count on "localtime" having been called.)
  3719. X * 
  3720. X * Revision 1.4  87/10/18  10:26:57  narten
  3721. X * Updating version numbers. Changes relative to 1.0 are actually 
  3722. X * relative to 1.2
  3723. X * 
  3724. X * Revision 1.3  87/09/24  13:58:45  narten
  3725. X * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  3726. X * warnings)
  3727. X * 
  3728. X * Revision 1.2  87/03/27  14:21:48  jenkins
  3729. X * Port to suns
  3730. X * 
  3731. X * Revision 1.1  84/01/23  14:50:04  kcs
  3732. X * Initial revision
  3733. X * 
  3734. X * Revision 1.2  83/12/05  10:12:56  wft
  3735. X * added cond. compilation for USG Unix; long timezone;
  3736. X * 
  3737. X * Revision 1.1  82/05/06  11:38:00  wft
  3738. X * Initial revision
  3739. X * 
  3740. X */
  3741. X
  3742. X
  3743. X#include "rcsbase.h"
  3744. X#include "time.h"
  3745. X
  3746. Xint daytb[] = {   /* # days in year thus far, indexed by month (0-12!!) */
  3747. X    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
  3748. X};
  3749. X
  3750. Xstruct tm *localtime();
  3751. Xlong    time();
  3752. X
  3753. Xlong maketime(atm)
  3754. Xstruct tm *atm;
  3755. X{    register struct tm *tp;
  3756. X    register int i;
  3757. X    int year, yday, mon, day, hour, min, sec, zone, dst, leap;
  3758. X    long tres, curtim;
  3759. X
  3760. X    VOID time(&curtim);
  3761. X    tp = localtime(&curtim);        /* Get breakdowns of current time */
  3762. X    year = tp->tm_year;        /* Use to set up defaults */
  3763. X    mon = tp->tm_mon;
  3764. X    day = tp->tm_mday;
  3765. X
  3766. X
  3767. X#ifdef DEBUG
  3768. Xprintf("first YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
  3769. X#endif
  3770. X    tp = atm;
  3771. X
  3772. X    /* First must find date, using specified year, month, day.
  3773. X     * If one of these is unspecified, it defaults either to the
  3774. X     * current date (if no more global spec was given) or to the
  3775. X     * zero-value for that spec (i.e. a more global spec was seen).
  3776. X     * Start with year... note 32 bits can only handle 135 years.
  3777. X     */
  3778. X    if(tp->tm_year != TMNULL)
  3779. X      {    if((year = tp->tm_year) >= 1900)    /* Allow full yr # */
  3780. X              year -= 1900;            /* by making kosher */
  3781. X        mon = 0;        /* Since year was given, default */
  3782. X        day = 1;        /* for remaining specs is zero */
  3783. X      }
  3784. X    if(year < 70 || 70+134 < year )    /* Check range */
  3785. X        return(0);        /* ERR: year out of range */
  3786. X    leap = year&03 ? 0 : 1;        /* See if leap year */
  3787. X    year -= 70;            /* UNIX time starts at 1970 */
  3788. X
  3789. X    /*
  3790. X     * Find day of year.
  3791. X     * YDAY is used only if it exists and either the month or day-of-month
  3792. X     * is missing.
  3793. X     */
  3794. X    if (tp->tm_yday != TMNULL
  3795. X     && (tp->tm_mon == TMNULL || tp->tm_mday == TMNULL))
  3796. X        yday = tp->tm_yday;
  3797. X    else
  3798. X      {    if(tp->tm_mon  != TMNULL)
  3799. X          {    mon = tp->tm_mon;    /* Month was specified */
  3800. X            day = 1;        /* so set remaining default */
  3801. X          }
  3802. X        if(mon < 0 || 11 < mon) return(0);    /* ERR: bad month */
  3803. X        if(tp->tm_mday != TMNULL) day = tp->tm_mday;
  3804. X        if(day < 1
  3805. X         || (((daytb[mon+1]-daytb[mon]) < day)
  3806. X            && (day!=29 || mon!=1 || !leap) ))
  3807. X                return(0);        /* ERR: bad day */
  3808. X        yday = daytb[mon]    /* Add # of days in months so far */
  3809. X          + ((leap        /* Leap year, and past Feb?  If */
  3810. X              && mon>1)? 1:0)    /* so, add leap day for this year */
  3811. X          + day-1;        /* And finally add # days this mon */
  3812. X
  3813. X                if (tp->tm_yday != TMNULL       /* Confirm that YDAY correct */
  3814. X                 && tp->tm_yday != yday) return(0);     /* ERR: conflict */
  3815. X      }
  3816. X    if(yday < 0 || (leap?366:365) <= yday)
  3817. X        return(0);        /* ERR: bad YDAY or maketime bug */
  3818. X
  3819. X    tres = year*365            /* Get # days of years so far */
  3820. X        + ((year+1)>>2)        /* plus # of leap days since 1970 */
  3821. X        + yday;            /* and finally add # days this year */
  3822. X
  3823. X        if((i = tp->tm_wday) != TMNULL) /* Check WDAY if present */
  3824. X                if(i < 0 || 6 < i       /* Ensure within range */
  3825. X                  || i != (tres+4)%7)   /* Matches? Jan 1,1970 was Thu = 4 */
  3826. X                        return(0);      /* ERR: bad WDAY */
  3827. X
  3828. X#ifdef DEBUG
  3829. Xprintf("YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
  3830. X#endif
  3831. X    /*
  3832. X     * Now determine time.  If not given, default to zeros
  3833. X     * (since time is always the least global spec)
  3834. X     */
  3835. X    tres *= 86400L;            /* Get # seconds (24*60*60) */
  3836. X    hour = min = sec = 0;
  3837. X    if(tp->tm_hour != TMNULL) hour = tp->tm_hour;
  3838. X    if(tp->tm_min  != TMNULL) min  = tp->tm_min;
  3839. X    if(tp->tm_sec  != TMNULL) sec  = tp->tm_sec;
  3840. X    if( min < 0 || 60 <= min
  3841. X     || sec < 0 || 60 <= sec) return(0);    /* ERR: MS out of range */
  3842. X    if(hour < 0 || 24 <= hour)
  3843. X        if(hour != 24 || (min+sec) !=0)    /* Allow 24:00 */
  3844. X            return(0);        /* ERR: H out of range */
  3845. X
  3846. X    /* confirm AM/PM if there */
  3847. X    switch(tp->tm_ampm)
  3848. X      {    case 0: case TMNULL:    /* Ignore these values */
  3849. X            break;
  3850. X        case 1:            /* AM */
  3851. X        case 2:            /* PM */
  3852. X            if(hour > 12) return(0);  /* ERR: hrs 13-23 bad */
  3853. X            if(hour ==12) hour = 0;    /* Modulo 12 */
  3854. X            if(tp->tm_ampm == 2)    /* If PM, then */
  3855. X                hour += 12;    /*   get 24-hour time */
  3856. X            break;
  3857. X        default: return(0);    /* ERR: illegal TM_AMPM value */
  3858. X      }
  3859. X
  3860. X    tres += sec + 60L*(min + 60L*hour);    /* Add in # secs of time */
  3861. X
  3862. X#ifdef DEBUG
  3863. Xprintf("HMS: %d %d %d T=%ld\n",hour,min,sec,tres);
  3864. X#endif
  3865. X    /*
  3866. X     * We now have the GMT date/time and must make final
  3867. X     * adjustment for the specified time zone.  If none is specified,
  3868. X     * the local time-zone is assumed.
  3869. X     */
  3870. X    if((zone = tp->tm_zon) == TMNULL    /* If unspecified */
  3871. X     || (zone == 1))            /* or local-zone requested */
  3872. X        zone = localzone();        /* then set to local zone */
  3873. X    if(zone < -24*60 || 24*60 <= zone)
  3874. X        return(0);            /* ERR: zone out of range */
  3875. X
  3876. X    /* See if must apply Daylight Saving Time shift.
  3877. X     * Note that if DST is specified, validity is not checked.
  3878. X     */
  3879. X    if((dst = tp->tm_isdst) == TMNULL)    /* Must we figure it out? */
  3880. X      {    curtim = tres +localzone()*60L;    /* Yuck.  Get equiv local */
  3881. X        dst = localtime(&curtim)->tm_isdst;     /* time, and ask. */
  3882. X      }
  3883. X    tres += zone*60L -(dst?3600:0);    /* Add in # seconds of zone adj */
  3884. X
  3885. X    return(tres);
  3886. X}
  3887. X
  3888. X
  3889. X/* LOCALZONE        return local timezone in # mins west of GMT
  3890. X *
  3891. X */
  3892. X
  3893. X#if defined(V6) || defined(USG)
  3894. Xextern long timezone;
  3895. X#else
  3896. X#include <sys/types.h>
  3897. X#include <sys/timeb.h>
  3898. X#endif
  3899. X
  3900. Xstatic int lclzon;
  3901. Xlocalzone()
  3902. X{
  3903. X    if (!lclzon) {
  3904. X#if defined(V6) || defined(USG)
  3905. X#ifdef USG
  3906. X    tzset();
  3907. X#endif
  3908. X    lclzon = timezone/60 + 1;
  3909. X#else
  3910. X    struct timeb tb;
  3911. X
  3912. X    ftime(&tb);
  3913. X    lclzon = tb.timezone + 1;
  3914. X
  3915. X#endif
  3916. X    }
  3917. X    return lclzon - 1;
  3918. X}
  3919. X@
  3920. X
  3921. X
  3922. X1.8.2.1
  3923. Xlog
  3924. X@Start of Amiga RCS port branch.
  3925. X@
  3926. Xtext
  3927. X@d23 1
  3928. Xa23 5
  3929. X<<<<<<< maketime.c
  3930. Xstatic char rcsid[]= "$Id: maketime.c,v 1.8.1.1 89/08/11 01:41:52 rsbx Exp Locker: rsbx $";
  3931. X=======
  3932. Xstatic char rcsid[]= "$Id: maketime.c,v 1.2 89/09/17 13:34:45 rick Exp $";
  3933. X>>>>>>> 1.2
  3934. Xa25 11
  3935. X<<<<<<< maketime.c
  3936. X * Revision 1.8.1.1  89/08/11  01:41:52  rsbx
  3937. X * Start of cbmvax RCS source branch.
  3938. X=======
  3939. X * Revision 1.2  89/09/17  13:34:45  rick
  3940. X * Port to AmigaDos done by Rick Schaeffer (ricks@@iscuva.iscs.com)
  3941. X * All changes done with conditional compile (#ifdef AMIGA).  This version
  3942. X * compiles correctly with Lattice C version 5.02 or later.
  3943. X>>>>>>> 1.2
  3944. X * 
  3945. X<<<<<<< maketime.c
  3946. Xa26 3
  3947. X * checked in with -k by rsbx at 89.08.10.16.02.32.
  3948. X * 
  3949. X * Revision 1.8  88/11/08  13:54:53  narten
  3950. Xa34 8
  3951. X=======
  3952. X * Revision 1.3  89/09/16  09:42:31  rick
  3953. X * Modified AMIGA changes to work with Lattice C
  3954. X * 
  3955. X * Revision 1.2  88/09/03  15:08:05  rick
  3956. X * Port to AmigaDos.  All done with conditional compiles
  3957. X * 
  3958. X>>>>>>> 1.2
  3959. Xd89 2
  3960. Xa90 1
  3961. X#ifdef MYDEBUG
  3962. Xa91 1
  3963. X<<<<<<< maketime.c
  3964. Xa92 3
  3965. X=======
  3966. X#endif MYDEBUG
  3967. X>>>>>>> 1.2
  3968. Xa106 3
  3969. X#ifdef AMIGA
  3970. X    if(year < 78 || 78+134 < year ) /* Check range */
  3971. X#else
  3972. Xa107 1
  3973. X#endif
  3974. Xa109 3
  3975. X#ifdef AMIGA
  3976. X    year -= 78;            /* AMIGA time starts at 1978 */
  3977. X#else
  3978. Xa110 1
  3979. X#endif
  3980. Xa116 1
  3981. X
  3982. Xa135 1
  3983. X#ifndef AMIGA            /* Manx's localtime messes up yday */
  3984. Xa137 1
  3985. X#endif
  3986. Xd143 1
  3987. Xa143 1
  3988. X        + ((year+1)>>2)        /* plus # of leap days since 1970 (1980)*/
  3989. Xa147 3
  3990. X#ifdef AMIGA
  3991. X                  || i != (tres+0)%7)   /* Matches? Jan 1,1978 was Sun = 0 */
  3992. X#else
  3993. Xa148 1
  3994. X#endif
  3995. Xd151 1
  3996. Xa151 1
  3997. X#ifdef MYDEBUG
  3998. Xa152 1
  3999. X<<<<<<< maketime.c
  4000. Xa153 3
  4001. X=======
  4002. X#endif MYDEBUG
  4003. X>>>>>>> 1.2
  4004. Xd163 4
  4005. Xa166 4
  4006. X    if( (min < 0) || (60 <= min)
  4007. X     || (sec < 0) || (60 <= sec) ) return(0);    /* ERR: MS out of range */
  4008. X    if((hour < 0) || (24 <= hour))
  4009. X        if((hour != 24) || ((min+sec) !=0))    /* Allow 24:00 */
  4010. Xa169 1
  4011. X#ifndef AMIGA
  4012. Xa181 1
  4013. X#endif
  4014. Xd185 1
  4015. Xa185 1
  4016. X#ifdef MYDEBUG
  4017. Xa186 1
  4018. X<<<<<<< maketime.c
  4019. Xa187 3
  4020. X=======
  4021. X#endif MYDEBUG
  4022. X>>>>>>> 1.2
  4023. Xa192 1
  4024. X#ifndef AMIGA
  4025. Xd207 1
  4026. Xa207 1
  4027. X#endif
  4028. Xa214 1
  4029. X<<<<<<< maketime.c
  4030. Xa216 4
  4031. X=======
  4032. X#ifndef AMIGA
  4033. X#ifdef V6
  4034. X>>>>>>> 1.2
  4035. Xa241 1
  4036. X#endif AMIGA
  4037. X@
  4038. X
  4039. X
  4040. X1.8.2.2
  4041. Xlog
  4042. X@Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
  4043. Xsources I have here (and are later than the ones Rick used).
  4044. X@
  4045. Xtext
  4046. X@d1 1
  4047. Xd23 5
  4048. Xa27 1
  4049. Xstatic char rcsid[]= "$Id: maketime.c,v 1.8.2.1 89/10/13 19:17:37 rsbx Exp Locker: rsbx $";
  4050. Xd30 1
  4051. Xa30 3
  4052. X * Revision 1.8.2.1  89/10/13  19:17:37  rsbx
  4053. X * Start of Amiga RCS port branch.
  4054. X * 
  4055. Xd33 6
  4056. Xd40 1
  4057. Xd53 8
  4058. Xd106 1
  4059. Xa106 4
  4060. X    int year, yday, mon, day, hour, min, sec, leap;
  4061. X#ifndef AMIGA
  4062. X    int zone, dst;
  4063. X#endif
  4064. Xd117 1
  4065. Xd119 3
  4066. Xd197 1
  4067. Xd199 3
  4068. Xd237 1
  4069. Xd239 3
  4070. Xd270 4
  4071. Xd275 2
  4072. Xa276 1
  4073. X#if defined(V6) || defined(USG)
  4074. X@
  4075. X
  4076. X
  4077. X1.8.1.1
  4078. Xlog
  4079. X@Start of cbmvax RCS source branch.
  4080. X@
  4081. Xtext
  4082. X@a26 3
  4083. X * checked in with -k by rsbx at 89.08.10.16.02.32.
  4084. X * 
  4085. X * Revision 1.8  88/11/08  13:54:53  narten
  4086. X@
  4087. SHAR_EOF
  4088. echo "End of archive 6 (of 14)"
  4089. # if you want to concatenate archives, remove anything after this line
  4090. exit
  4091.